diff --git a/README.md b/README.md index 65d1122..f031a80 100644 --- a/README.md +++ b/README.md @@ -48,15 +48,22 @@ Tagline: **Lens collect partial carbon retirements** ## Implementation -### Partial carbon retirement collect module (PCRCM) -- use KlimaDAO's retirement aggregator (RA) for maximum flexibility https://github.com/KlimaDAO/klimadao-solidity/tree/main/src/infinity -- RA performs the token swap from collect currency to carbon token and the token retirement -- allow any collect currency that is whitelisted by Lens and any carbon token that is included in the RA -- at module init, check if swap path & liquidity exists. If not, revert. -- at collect process, check if swap path & liquidity exists. If not: - - process collect without retirement (do not revert) - - send retirement amount to publisher, deduct treasury fee, but send an event on blockchain to signal to publisher that they should perform retirement manually to cover all such failed retirements. -- include retirement messages to make it possible to search for all retirements by a Lens profile, publication - -### Frontend -- follow Lenster +- Set collection rule: choose "carbon percentage" instead of everything +- Collection workflow: make visible that collection will retire carbon + +# Repository structure + +The repo consists of different more or less dependent folders. Each one contains an own readme. + +- **hardhat**: +- **lens-app**: A separate frontend from the hackathon +- **lens-protocol**: Local copy of github/lens-protocol, contains all functionality of lens protocol and our smart contracts +- **lenster-main**: Local copy of github/lenster, frontend of Lenster with our modifications +- **utils**: Folder with helper stuff + +# Deployments +## Lenster app local deployment (Frontend) +See readme in lenster-main + +## Deploy Lens protocol on local fork (Smart Contracts) +See readme in lens-protocol diff --git a/lens-app/app/layout.tsx b/lens-app/app/layout.tsx index 0a1855b..c266f5f 100644 --- a/lens-app/app/layout.tsx +++ b/lens-app/app/layout.tsx @@ -2,12 +2,19 @@ import './globals.css' import { configureChains, createClient, WagmiConfig } from 'wagmi' //import { mainnet, polygon } from 'wagmi/chains' -import { goerli, polygonMumbai } from 'wagmi/chains' +import { polygon, polygonMumbai, localhost } from 'wagmi/chains' import { publicProvider } from 'wagmi/providers/public' -import { LensProvider, LensConfig, development } from '@lens-protocol/react-web' + +import { LensProvider, LensConfig, development, production } from '@lens-protocol/react-web' import { bindings as wagmiBindings } from '@lens-protocol/wagmi' //const { provider, webSocketProvider } = configureChains([polygon, mainnet], [publicProvider()]) -const { provider, webSocketProvider } = configureChains([polygonMumbai, goerli], [publicProvider()]) +const { provider, webSocketProvider } = configureChains( + [ + //polygonMumbai, + //polygon, + localhost], + [publicProvider()] + ) const client = createClient({ autoConnect: true, @@ -17,6 +24,7 @@ const client = createClient({ const lensConfig: LensConfig = { bindings: wagmiBindings(), + //environment: development, environment: development, }; diff --git a/lens-app/package-lock.json b/lens-app/package-lock.json index 11c091f..9d6c362 100644 --- a/lens-app/package-lock.json +++ b/lens-app/package-lock.json @@ -14,13 +14,14 @@ "@types/react": "18.2.9", "@types/react-dom": "18.2.4", "autoprefixer": "10.4.14", + "encoding": "0.1.13", "eslint": "8.42.0", "eslint-config-next": "13.4.4", "ethers": "^5.7.2", - "next": "13.4.4", + "next": "^13.4.19", "postcss": "8.4.24", - "react": "18.2.0", - "react-dom": "18.2.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "tailwindcss": "3.3.2", "typescript": "5.1.3", "wagmi": "^0.12.7" @@ -1442,9 +1443,9 @@ } }, "node_modules/@next/env": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.4.tgz", - "integrity": "sha512-q/y7VZj/9YpgzDe64Zi6rY1xPizx80JjlU2BTevlajtaE3w1LqweH1gGgxou2N7hdFosXHjGrI4OUvtFXXhGLg==" + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.19.tgz", + "integrity": "sha512-FsAT5x0jF2kkhNkKkukhsyYOrRqtSxrEhfliniIq0bwWbuXLgyt3Gv0Ml+b91XwjwArmuP7NxCiGd++GGKdNMQ==" }, "node_modules/@next/eslint-plugin-next": { "version": "13.4.4", @@ -1455,9 +1456,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.4.tgz", - "integrity": "sha512-xfjgXvp4KalNUKZMHmsFxr1Ug+aGmmO6NWP0uoh4G3WFqP/mJ1xxfww0gMOeMeSq/Jyr5k7DvoZ2Pv+XOITTtw==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.19.tgz", + "integrity": "sha512-vv1qrjXeGbuF2mOkhkdxMDtv9np7W4mcBtaDnHU+yJG+bBwa6rYsYSCI/9Xm5+TuF5SbZbrWO6G1NfTh1TMjvQ==", "cpu": [ "arm64" ], @@ -1470,9 +1471,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.4.tgz", - "integrity": "sha512-ZY9Ti1hkIwJsxGus3nlubIkvYyB0gNOYxKrfsOrLEqD0I2iCX8D7w8v6QQZ2H+dDl6UT29oeEUdDUNGk4UEpfg==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.19.tgz", + "integrity": "sha512-jyzO6wwYhx6F+7gD8ddZfuqO4TtpJdw3wyOduR4fxTUCm3aLw7YmHGYNjS0xRSYGAkLpBkH1E0RcelyId6lNsw==", "cpu": [ "x64" ], @@ -1485,9 +1486,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.4.tgz", - "integrity": "sha512-+KZnDeMShYkpkqAvGCEDeqYTRADJXc6SY1jWXz+Uo6qWQO/Jd9CoyhTJwRSxvQA16MoYzvILkGaDqirkRNctyA==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.19.tgz", + "integrity": "sha512-vdlnIlaAEh6H+G6HrKZB9c2zJKnpPVKnA6LBwjwT2BTjxI7e0Hx30+FoWCgi50e+YO49p6oPOtesP9mXDRiiUg==", "cpu": [ "arm64" ], @@ -1500,9 +1501,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.4.tgz", - "integrity": "sha512-evC1twrny2XDT4uOftoubZvW3EG0zs0ZxMwEtu/dDGVRO5n5pT48S8qqEIBGBUZYu/Xx4zzpOkIxx1vpWdE+9A==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.19.tgz", + "integrity": "sha512-aU0HkH2XPgxqrbNRBFb3si9Ahu/CpaR5RPmN2s9GiM9qJCiBBlZtRTiEca+DC+xRPyCThTtWYgxjWHgU7ZkyvA==", "cpu": [ "arm64" ], @@ -1515,9 +1516,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.4.tgz", - "integrity": "sha512-PX706XcCHr2FfkyhP2lpf+pX/tUvq6/ke7JYnnr0ykNdEMo+sb7cC/o91gnURh4sPYSiZJhsF2gbIqg9rciOHQ==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.19.tgz", + "integrity": "sha512-htwOEagMa/CXNykFFeAHHvMJeqZfNQEoQvHfsA4wgg5QqGNqD5soeCer4oGlCol6NGUxknrQO6VEustcv+Md+g==", "cpu": [ "x64" ], @@ -1530,9 +1531,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.4.tgz", - "integrity": "sha512-TKUUx3Ftd95JlHV6XagEnqpT204Y+IsEa3awaYIjayn0MOGjgKZMZibqarK3B1FsMSPaieJf2FEAcu9z0yT5aA==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.19.tgz", + "integrity": "sha512-4Gj4vvtbK1JH8ApWTT214b3GwUh9EKKQjY41hH/t+u55Knxi/0wesMzwQRhppK6Ddalhu0TEttbiJ+wRcoEj5Q==", "cpu": [ "x64" ], @@ -1545,9 +1546,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.4.tgz", - "integrity": "sha512-FP8AadgSq4+HPtim7WBkCMGbhr5vh9FePXiWx9+YOdjwdQocwoCK5ZVC3OW8oh3TWth6iJ0AXJ/yQ1q1cwSZ3A==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.19.tgz", + "integrity": "sha512-bUfDevQK4NsIAHXs3/JNgnvEY+LRyneDN788W2NYiRIIzmILjba7LaQTfihuFawZDhRtkYCv3JDC3B4TwnmRJw==", "cpu": [ "arm64" ], @@ -1560,9 +1561,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.4.tgz", - "integrity": "sha512-3WekVmtuA2MCdcAOrgrI+PuFiFURtSyyrN1I3UPtS0ckR2HtLqyqmS334Eulf15g1/bdwMteePdK363X/Y9JMg==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.19.tgz", + "integrity": "sha512-Y5kikILFAr81LYIFaw6j/NrOtmiM4Sf3GtOc0pn50ez2GCkr+oejYuKGcwAwq3jiTKuzF6OF4iT2INPoxRycEA==", "cpu": [ "ia32" ], @@ -1575,9 +1576,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.4.tgz", - "integrity": "sha512-AHRITu/CrlQ+qzoqQtEMfaTu7GHaQ6bziQln/pVWpOYC1wU+Mq6VQQFlsDtMCnDztPZtppAXdvvbNS7pcfRzlw==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.19.tgz", + "integrity": "sha512-YzA78jBDXMYiINdPdJJwGgPNT3YqBNNGhsthsDoWHL9p24tEJn9ViQf/ZqTbwSpX/RrkPupLfuuTH2sf73JBAw==", "cpu": [ "x64" ], @@ -4146,6 +4147,14 @@ "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==" }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -5204,6 +5213,11 @@ "node": ">=10.13.0" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, "node_modules/globals": { "version": "13.20.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", @@ -5424,6 +5438,17 @@ "ms": "^2.0.0" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -6598,16 +6623,17 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/next": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/next/-/next-13.4.4.tgz", - "integrity": "sha512-C5S0ysM0Ily9McL4Jb48nOQHT1BukOWI59uC3X/xCMlYIh9rJZCv7nzG92J6e1cOBqQbKovlpgvHWFmz4eKKEA==", + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/next/-/next-13.4.19.tgz", + "integrity": "sha512-HuPSzzAbJ1T4BD8e0bs6B9C1kWQ6gv8ykZoRWs5AQoiIuqbGHHdQO7Ljuvg05Q0Z24E2ABozHe6FxDvI6HfyAw==", "dependencies": { - "@next/env": "13.4.4", + "@next/env": "13.4.19", "@swc/helpers": "0.5.1", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", "postcss": "8.4.14", "styled-jsx": "5.1.1", + "watchpack": "2.4.0", "zod": "3.21.4" }, "bin": { @@ -6617,19 +6643,18 @@ "node": ">=16.8.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "13.4.4", - "@next/swc-darwin-x64": "13.4.4", - "@next/swc-linux-arm64-gnu": "13.4.4", - "@next/swc-linux-arm64-musl": "13.4.4", - "@next/swc-linux-x64-gnu": "13.4.4", - "@next/swc-linux-x64-musl": "13.4.4", - "@next/swc-win32-arm64-msvc": "13.4.4", - "@next/swc-win32-ia32-msvc": "13.4.4", - "@next/swc-win32-x64-msvc": "13.4.4" + "@next/swc-darwin-arm64": "13.4.19", + "@next/swc-darwin-x64": "13.4.19", + "@next/swc-linux-arm64-gnu": "13.4.19", + "@next/swc-linux-arm64-musl": "13.4.19", + "@next/swc-linux-x64-gnu": "13.4.19", + "@next/swc-linux-x64-musl": "13.4.19", + "@next/swc-win32-arm64-msvc": "13.4.19", + "@next/swc-win32-ia32-msvc": "13.4.19", + "@next/swc-win32-x64-msvc": "13.4.19" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", - "fibers": ">= 3.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" @@ -6638,9 +6663,6 @@ "@opentelemetry/api": { "optional": true }, - "fibers": { - "optional": true - }, "sass": { "optional": true } @@ -7759,6 +7781,11 @@ "node": ">=10" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -8668,6 +8695,18 @@ } } }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/web-vitals": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.3.2.tgz", diff --git a/lens-app/package.json b/lens-app/package.json index 94cbc22..0100663 100644 --- a/lens-app/package.json +++ b/lens-app/package.json @@ -19,10 +19,10 @@ "eslint": "8.42.0", "eslint-config-next": "13.4.4", "ethers": "^5.7.2", - "next": "13.4.4", + "next": "^13.4.19", "postcss": "8.4.24", - "react": "18.2.0", - "react-dom": "18.2.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "tailwindcss": "3.3.2", "typescript": "5.1.3", "wagmi": "^0.12.7" diff --git a/lens-app/yarn.lock b/lens-app/yarn.lock index 873fb58..f266a2c 100644 --- a/lens-app/yarn.lock +++ b/lens-app/yarn.lock @@ -4,12 +4,12 @@ "@alloc/quick-lru@^5.2.0": version "5.2.0" - resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz" integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== "@apollo/client@^3.7.1": version "3.7.15" - resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.7.15.tgz#59dbeb5d64479f8ce0af321d8c0bf6df1d873e2d" + resolved "https://registry.npmjs.org/@apollo/client/-/client-3.7.15.tgz" integrity sha512-pLScjo4GAQRWKWyEg2J3FlQr9fbUAuADT0EI2+JlLf2BjaU9I7WUaZVD9w+0qNPE8BZqs53MRQq0OCm1QCW+eg== dependencies: "@graphql-typed-document-node/core" "^3.1.1" @@ -28,14 +28,14 @@ "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.20.7": version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz" integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA== dependencies: regenerator-runtime "^0.13.11" -"@coinbase/wallet-sdk@^3.6.6": +"@coinbase/wallet-sdk@^3.5.4": version "3.6.6" - resolved "https://registry.yarnpkg.com/@coinbase/wallet-sdk/-/wallet-sdk-3.6.6.tgz#4a0758fe0fe0ba3ed7e33b5bb6eb094ff8bd6c98" + resolved "https://registry.npmjs.org/@coinbase/wallet-sdk/-/wallet-sdk-3.6.6.tgz" integrity sha512-vX+epj/Ttjo7XRwlr3TFUUfW5GTRMvORpERPwiu7z2jl3DSVL4rXLmHt5y6LDPlUVreas2gumdcFbu0fLRG9Jg== dependencies: "@metamask/safe-event-emitter" "2.0.0" @@ -56,21 +56,28 @@ stream-browserify "^3.0.0" util "^0.12.4" +"@cspotcode/source-map-support@^0.8.0": + 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== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.4.0": version "4.5.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== "@eslint/eslintrc@^2.0.3": version "2.0.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz" integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== dependencies: ajv "^6.12.4" @@ -85,12 +92,12 @@ "@eslint/js@8.42.0": version "8.42.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.42.0.tgz#484a1d638de2911e6f5a30c12f49c7e4a3270fb6" + resolved "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz" integrity sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw== -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": +"@ethersproject/abi@^5.7.0", "@ethersproject/abi@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + resolved "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz" integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== dependencies: "@ethersproject/address" "^5.7.0" @@ -103,9 +110,9 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": +"@ethersproject/abstract-provider@^5.7.0", "@ethersproject/abstract-provider@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" + resolved "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz" integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== dependencies: "@ethersproject/bignumber" "^5.7.0" @@ -116,9 +123,9 @@ "@ethersproject/transactions" "^5.7.0" "@ethersproject/web" "^5.7.0" -"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": +"@ethersproject/abstract-signer@^5.7.0", "@ethersproject/abstract-signer@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" + resolved "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz" integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== dependencies: "@ethersproject/abstract-provider" "^5.7.0" @@ -127,9 +134,9 @@ "@ethersproject/logger" "^5.7.0" "@ethersproject/properties" "^5.7.0" -"@ethersproject/address@5.7.0", "@ethersproject/address@^5.7.0": +"@ethersproject/address@^5.7.0", "@ethersproject/address@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" + resolved "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz" integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== dependencies: "@ethersproject/bignumber" "^5.7.0" @@ -138,47 +145,47 @@ "@ethersproject/logger" "^5.7.0" "@ethersproject/rlp" "^5.7.0" -"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": +"@ethersproject/base64@^5.7.0", "@ethersproject/base64@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" + resolved "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz" integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== dependencies: "@ethersproject/bytes" "^5.7.0" -"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": +"@ethersproject/basex@^5.7.0", "@ethersproject/basex@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" + resolved "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz" integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/properties" "^5.7.0" -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": +"@ethersproject/bignumber@^5.7.0", "@ethersproject/bignumber@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" + resolved "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz" integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/logger" "^5.7.0" bn.js "^5.2.1" -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": +"@ethersproject/bytes@^5.7.0", "@ethersproject/bytes@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" + resolved "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz" integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": +"@ethersproject/constants@^5.7.0", "@ethersproject/constants@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" + resolved "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz" integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== dependencies: "@ethersproject/bignumber" "^5.7.0" -"@ethersproject/contracts@5.7.0": +"@ethersproject/contracts@^5.2.0", "@ethersproject/contracts@^5.7.0", "@ethersproject/contracts@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" + resolved "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz" integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== dependencies: "@ethersproject/abi" "^5.7.0" @@ -192,9 +199,9 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/transactions" "^5.7.0" -"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": +"@ethersproject/hash@^5.4.0", "@ethersproject/hash@^5.7.0", "@ethersproject/hash@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" + resolved "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz" integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== dependencies: "@ethersproject/abstract-signer" "^5.7.0" @@ -207,9 +214,9 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": +"@ethersproject/hdnode@^5.7.0", "@ethersproject/hdnode@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" + resolved "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz" integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== dependencies: "@ethersproject/abstract-signer" "^5.7.0" @@ -225,9 +232,9 @@ "@ethersproject/transactions" "^5.7.0" "@ethersproject/wordlists" "^5.7.0" -"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": +"@ethersproject/json-wallets@^5.7.0", "@ethersproject/json-wallets@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" + resolved "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz" integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== dependencies: "@ethersproject/abstract-signer" "^5.7.0" @@ -244,44 +251,44 @@ aes-js "3.0.0" scrypt-js "3.0.1" -"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": +"@ethersproject/keccak256@^5.7.0", "@ethersproject/keccak256@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + resolved "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz" integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== dependencies: "@ethersproject/bytes" "^5.7.0" js-sha3 "0.8.0" -"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": +"@ethersproject/logger@^5.7.0", "@ethersproject/logger@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + resolved "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz" integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== -"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": +"@ethersproject/networks@^5.7.0", "@ethersproject/networks@5.7.1": version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" + resolved "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz" integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": +"@ethersproject/pbkdf2@^5.7.0", "@ethersproject/pbkdf2@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" + resolved "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz" integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/sha2" "^5.7.0" -"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": +"@ethersproject/properties@^5.7.0", "@ethersproject/properties@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" + resolved "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz" integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.2": +"@ethersproject/providers@^5.2.0", "@ethersproject/providers@^5.7.2", "@ethersproject/providers@5.7.2": version "5.7.2" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" + resolved "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz" integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== dependencies: "@ethersproject/abstract-provider" "^5.7.0" @@ -305,34 +312,34 @@ bech32 "1.1.4" ws "7.4.6" -"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": +"@ethersproject/random@^5.7.0", "@ethersproject/random@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" + resolved "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz" integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": +"@ethersproject/rlp@^5.7.0", "@ethersproject/rlp@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" + resolved "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz" integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": +"@ethersproject/sha2@^5.7.0", "@ethersproject/sha2@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" + resolved "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz" integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/logger" "^5.7.0" hash.js "1.1.7" -"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": +"@ethersproject/signing-key@^5.7.0", "@ethersproject/signing-key@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" + resolved "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz" integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== dependencies: "@ethersproject/bytes" "^5.7.0" @@ -344,7 +351,7 @@ "@ethersproject/solidity@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" + resolved "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz" integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== dependencies: "@ethersproject/bignumber" "^5.7.0" @@ -354,18 +361,18 @@ "@ethersproject/sha2" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": +"@ethersproject/strings@^5.7.0", "@ethersproject/strings@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" + resolved "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz" integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": +"@ethersproject/transactions@^5.7.0", "@ethersproject/transactions@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" + resolved "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz" integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== dependencies: "@ethersproject/address" "^5.7.0" @@ -380,16 +387,16 @@ "@ethersproject/units@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" + resolved "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz" integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== dependencies: "@ethersproject/bignumber" "^5.7.0" "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/wallet@5.7.0": +"@ethersproject/wallet@^5.2.0", "@ethersproject/wallet@^5.7.0", "@ethersproject/wallet@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" + resolved "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz" integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== dependencies: "@ethersproject/abstract-provider" "^5.7.0" @@ -408,9 +415,9 @@ "@ethersproject/transactions" "^5.7.0" "@ethersproject/wordlists" "^5.7.0" -"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": +"@ethersproject/web@^5.7.0", "@ethersproject/web@5.7.1": version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" + resolved "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz" integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== dependencies: "@ethersproject/base64" "^5.7.0" @@ -419,9 +426,9 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": +"@ethersproject/wordlists@^5.7.0", "@ethersproject/wordlists@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" + resolved "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz" integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== dependencies: "@ethersproject/bytes" "^5.7.0" @@ -432,12 +439,12 @@ "@graphql-typed-document-node/core@^3.1.1": version "3.2.0" - resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" + resolved "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz" integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== "@humanwhocodes/config-array@^0.11.10": version "0.11.10" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz" integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== dependencies: "@humanwhocodes/object-schema" "^1.2.1" @@ -446,54 +453,62 @@ "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz" integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0": +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@3.1.0": version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== "@jridgewell/set-array@^1.0.1": version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@1.4.14": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + "@jridgewell/trace-mapping@^0.3.9": version "0.3.18" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz" integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== dependencies: "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@json-rpc-tools/provider@^1.5.5": version "1.7.6" - resolved "https://registry.yarnpkg.com/@json-rpc-tools/provider/-/provider-1.7.6.tgz#8a17c34c493fa892632e278fd9331104e8491ec6" + resolved "https://registry.npmjs.org/@json-rpc-tools/provider/-/provider-1.7.6.tgz" integrity sha512-z7D3xvJ33UfCGv77n40lbzOYjZKVM3k2+5cV7xS8G6SCvKTzMkhkUYuD/qzQUNT4cG/lv0e9mRToweEEVLVVmA== dependencies: "@json-rpc-tools/utils" "^1.7.6" @@ -503,14 +518,14 @@ "@json-rpc-tools/types@^1.7.6": version "1.7.6" - resolved "https://registry.yarnpkg.com/@json-rpc-tools/types/-/types-1.7.6.tgz#5abd5fde01364a130c46093b501715bcce5bdc0e" + resolved "https://registry.npmjs.org/@json-rpc-tools/types/-/types-1.7.6.tgz" integrity sha512-nDSqmyRNEqEK9TZHtM15uNnDljczhCUdBmRhpNZ95bIPKEDQ+nTDmGMFd2lLin3upc5h2VVVd9tkTDdbXUhDIQ== dependencies: keyvaluestorage-interface "^1.0.0" "@json-rpc-tools/utils@^1.7.6": version "1.7.6" - resolved "https://registry.yarnpkg.com/@json-rpc-tools/utils/-/utils-1.7.6.tgz#67f04987dbaa2e7adb6adff1575367b75a9a9ba1" + resolved "https://registry.npmjs.org/@json-rpc-tools/utils/-/utils-1.7.6.tgz" integrity sha512-HjA8x/U/Q78HRRe19yh8HVKoZ+Iaoo3YZjakJYxR+rw52NHo6jM+VE9b8+7ygkCFXl/EHID5wh/MkXaE/jGyYw== dependencies: "@json-rpc-tools/types" "^1.7.6" @@ -518,12 +533,12 @@ "@ledgerhq/connect-kit-loader@^1.0.1": version "1.0.2" - resolved "https://registry.yarnpkg.com/@ledgerhq/connect-kit-loader/-/connect-kit-loader-1.0.2.tgz#8554e16943f86cc2a5f6348a14dfe6e5bd0c572a" + resolved "https://registry.npmjs.org/@ledgerhq/connect-kit-loader/-/connect-kit-loader-1.0.2.tgz" integrity sha512-TQ21IjcZOw/scqypaVFY3jHVqI7X7Hta3qN/us6FvTol3AY06UmrhhXGww0E9xHmAbdX241ddwXEiMBSQZFr9g== "@lens-protocol/api-bindings@0.8.0": version "0.8.0" - resolved "https://registry.yarnpkg.com/@lens-protocol/api-bindings/-/api-bindings-0.8.0.tgz#78978b00fca5b5e8b1bb1e181293c29b94a987b6" + resolved "https://registry.npmjs.org/@lens-protocol/api-bindings/-/api-bindings-0.8.0.tgz" integrity sha512-O78sRg2D6zIKyaRAIytFrDaByWgi2MYJ57LnJ0A2enyIE2iHTBO/QBxfHIsVppKAUcSi2tqmS5gcG2ZRlSIW9A== dependencies: "@apollo/client" "^3.7.1" @@ -535,7 +550,7 @@ "@lens-protocol/blockchain-bindings@0.8.0": version "0.8.0" - resolved "https://registry.yarnpkg.com/@lens-protocol/blockchain-bindings/-/blockchain-bindings-0.8.0.tgz#4925a32ff389e34f352bbb2e85f973a840f7666e" + resolved "https://registry.npmjs.org/@lens-protocol/blockchain-bindings/-/blockchain-bindings-0.8.0.tgz" integrity sha512-uk46bJcv9bFAeT55CFKwA+67l0np1ESb+WcOFztFzemiCqSPv3EtAZQDTEGILG1w6bEFrcE+IyzEt/X6aphsrQ== dependencies: "@ethersproject/abi" "^5.7.0" @@ -547,7 +562,7 @@ "@lens-protocol/domain@0.8.0": version "0.8.0" - resolved "https://registry.yarnpkg.com/@lens-protocol/domain/-/domain-0.8.0.tgz#47f940ee7f24ef48d6af7cb0e690b873ddf486f4" + resolved "https://registry.npmjs.org/@lens-protocol/domain/-/domain-0.8.0.tgz" integrity sha512-x85hoci1g95bvFZ2JJ+rwLb8vFKUXXQH01NeX2exhjTAO/s6E3TkE/7ShJLpfHDvEv3n971d7ud94M+DwJNB0w== dependencies: "@lens-protocol/shared-kernel" "0.8.0" @@ -555,7 +570,7 @@ "@lens-protocol/gated-content@0.2.2": version "0.2.2" - resolved "https://registry.yarnpkg.com/@lens-protocol/gated-content/-/gated-content-0.2.2.tgz#10c651aaf9f6d0785b1a6c619cf97826f194f15a" + resolved "https://registry.npmjs.org/@lens-protocol/gated-content/-/gated-content-0.2.2.tgz" integrity sha512-joCHPjVyYmsXHjmIwc8Oh/tsXc7MRxNS4obxXRGCWRnrj35NvixpqCbG2msYnb/TKgj7A7/8ielRaU0DyecDXg== dependencies: "@ethersproject/address" "^5.7.0" @@ -572,9 +587,9 @@ siwe "^1.1.6" tslib "^2.5.0" -"@lens-protocol/react-web@^1.1.0": +"@lens-protocol/react-web@^1.1.0", "@lens-protocol/react-web@1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@lens-protocol/react-web/-/react-web-1.1.0.tgz#694ba757d0e6d0a8ade7a1579de77ac9c6e0439f" + resolved "https://registry.npmjs.org/@lens-protocol/react-web/-/react-web-1.1.0.tgz" integrity sha512-adCpOZ2gzpyqqwot/2sYClf87gi+iIlMUZZPzBgecVlwbLZtHE6ZRjW7n5FgSIFJV83LIwPtwd73RC/FQb1x/A== dependencies: "@lens-protocol/api-bindings" "0.8.0" @@ -586,7 +601,7 @@ "@lens-protocol/react@1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@lens-protocol/react/-/react-1.1.0.tgz#ae314ecc526eb466cb3fef0d1ce0d77175fe8176" + resolved "https://registry.npmjs.org/@lens-protocol/react/-/react-1.1.0.tgz" integrity sha512-qxYY6tMBfVnrael05lGyh1vPU0apDTaVEadTpr0dQB/Fq4vUHm3evKJt73ixEPFKozG8Yhqs8eAn6g3Va02mmA== dependencies: "@apollo/client" "^3.7.1" @@ -607,7 +622,7 @@ "@lens-protocol/shared-kernel@0.8.0": version "0.8.0" - resolved "https://registry.yarnpkg.com/@lens-protocol/shared-kernel/-/shared-kernel-0.8.0.tgz#026af63b944dad31b1f4c5ec703d884d3cd184c7" + resolved "https://registry.npmjs.org/@lens-protocol/shared-kernel/-/shared-kernel-0.8.0.tgz" integrity sha512-CA4msIepeTC5KfkXfeSWvR8iN1cPStmBrhhTWrLgUWpwTRQpy/ZY9E7PWzBt6Pi6sbohHWsUyrl6QW83huCppg== dependencies: decimal.js "^10.4.3" @@ -617,7 +632,7 @@ "@lens-protocol/storage@0.7.2": version "0.7.2" - resolved "https://registry.yarnpkg.com/@lens-protocol/storage/-/storage-0.7.2.tgz#e026ad9a950d77d43b565e09906b55afff46c9d1" + resolved "https://registry.npmjs.org/@lens-protocol/storage/-/storage-0.7.2.tgz" integrity sha512-bRXe0WfjbdMEtzL5zBJnqrUeHxXPcyjuiWLACnSpt4HrwCefzdXjq2h96+0yRCmp2FPrRasMUVnLauM+M3Kn0A== dependencies: "@lens-protocol/shared-kernel" "0.8.0" @@ -626,19 +641,19 @@ "@lens-protocol/wagmi@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@lens-protocol/wagmi/-/wagmi-1.1.0.tgz#15266b5764eb7075d5281b549023ab884a6fe9d6" + resolved "https://registry.npmjs.org/@lens-protocol/wagmi/-/wagmi-1.1.0.tgz" integrity sha512-SRITvha5sd1VKymY5QMpdHbCWrF/exIXqx+La0nto+kSyfcA44ofwmYz8gKXRy3mAlOoXpv91yXO6jd1kNF+Gw== dependencies: "@lens-protocol/shared-kernel" "0.8.0" "@lit-labs/ssr-dom-shim@^1.0.0", "@lit-labs/ssr-dom-shim@^1.1.0": version "1.1.1" - resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz#64df34e2f12e68e78ac57e571d25ec07fa460ca9" + resolved "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz" integrity sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ== "@lit-protocol/access-control-conditions@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/access-control-conditions/-/access-control-conditions-2.1.62.tgz#7df9e0a90482f8d75fee23c4b97922467626ee7b" + resolved "https://registry.npmjs.org/@lit-protocol/access-control-conditions/-/access-control-conditions-2.1.62.tgz" integrity sha512-nP+iqiLUzQa6bfZL9hM9a+s+YVW21HoHkHP7s2E11VFQmucdnJmUUr7Aw46SK/4yClTjLb6RuHyfIPvCdmIKhQ== dependencies: "@lit-protocol/constants" "2.1.62" @@ -650,7 +665,7 @@ "@lit-protocol/auth-browser@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/auth-browser/-/auth-browser-2.1.62.tgz#3050f195da2a89e8d238c89f5b4f5d828581b527" + resolved "https://registry.npmjs.org/@lit-protocol/auth-browser/-/auth-browser-2.1.62.tgz" integrity sha512-/4BTl0omR+JUCyJJc93FCiygSn/4ldrbeBuzWYQzuOFh2f6fcY1GJe3ttEoSJUfwu7OblW86YpWAT65b56rACA== dependencies: "@lit-protocol/constants" "2.1.62" @@ -670,12 +685,12 @@ "@lit-protocol/bls-sdk@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/bls-sdk/-/bls-sdk-2.1.62.tgz#23cf3c840b15b8d85ad6a751ef98ddfd6cce555a" + resolved "https://registry.npmjs.org/@lit-protocol/bls-sdk/-/bls-sdk-2.1.62.tgz" integrity sha512-UjNjycoNXOEoLH/foIJx1L9PLL5OxmHcCD/mFXr4KSeQV/v4srvGNpY/4ng7+k9sJEbvwRwv+FB07ng3/Ihacg== "@lit-protocol/constants@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/constants/-/constants-2.1.62.tgz#2703e8905c7ec06a9690b42ae8f5706ebd2d23af" + resolved "https://registry.npmjs.org/@lit-protocol/constants/-/constants-2.1.62.tgz" integrity sha512-4CigP3GS7Cxpa9RXT1twCCvYI5wvfo1UAMbdrjoDgM9VMDtpvSrmlG8AwC9yMoqPM6409BYcgGI9LDGzUjNUjg== dependencies: "@lit-protocol/types" "2.1.62" @@ -683,7 +698,7 @@ "@lit-protocol/crypto@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/crypto/-/crypto-2.1.62.tgz#637e9cbdd14d41284ddcd7f32c43547ebdd6843f" + resolved "https://registry.npmjs.org/@lit-protocol/crypto/-/crypto-2.1.62.tgz" integrity sha512-pWte+VQOPmSFvfoMxvobmj5JjkGSD44XMkkTXGubpGTBr27hK9CuDxpVHTsI9NsGFSJRdPBpRou+YD5I22yDiA== dependencies: "@lit-protocol/bls-sdk" "2.1.62" @@ -698,12 +713,12 @@ "@lit-protocol/ecdsa-sdk@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/ecdsa-sdk/-/ecdsa-sdk-2.1.62.tgz#5b98aefc8a37b1efdf5f35138cd0ef381e9ee4f8" + resolved "https://registry.npmjs.org/@lit-protocol/ecdsa-sdk/-/ecdsa-sdk-2.1.62.tgz" integrity sha512-VWYAQh31e5Vu6YXvw7iDQja/f2Je6Obj8VoXLweWWfSpUnKqe1JJKGDLxOAuQUT3ZSaX7bYrq7hLIJdwdWmJQw== "@lit-protocol/encryption@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/encryption/-/encryption-2.1.62.tgz#c020842a7b03a4b3cc62db0c93ac17426d29780a" + resolved "https://registry.npmjs.org/@lit-protocol/encryption/-/encryption-2.1.62.tgz" integrity sha512-Nmte/UINgc+YVlA3RewhW+1SFnKcSikd94HlBxS+TX9yb2KBUO6oKNjTQSGX4P/KD3zBxaFlbY8+jrWeYR1aQQ== dependencies: "@lit-protocol/bls-sdk" "2.1.62" @@ -720,12 +735,12 @@ "@lit-protocol/lit-third-party-libs@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/lit-third-party-libs/-/lit-third-party-libs-2.1.62.tgz#51486097e0936cfe73ce2c1d90ef566e447e90b1" + resolved "https://registry.npmjs.org/@lit-protocol/lit-third-party-libs/-/lit-third-party-libs-2.1.62.tgz" integrity sha512-js8Z3uG4v30Dw9HNqnjxkzMcB3cp3UcF6tfsWGo99+g5OqqKnkCDbb4IXeqnGbslVPn6ll6XouRQPmCcuzeGaw== "@lit-protocol/misc-browser@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/misc-browser/-/misc-browser-2.1.62.tgz#457cc75075139cd56b060a76a28e24df4b9bb907" + resolved "https://registry.npmjs.org/@lit-protocol/misc-browser/-/misc-browser-2.1.62.tgz" integrity sha512-2NX//tUe5ChrWCN4Msi4RE8DlYjTMGqyPYJHS86r7nKHG7sHSPCucn84LiTmVGA3DVKzspeGJdMbEF/W8Ogn6w== dependencies: "@lit-protocol/constants" "2.1.62" @@ -737,7 +752,7 @@ "@lit-protocol/misc@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/misc/-/misc-2.1.62.tgz#6fc1246a66c7a38489a515274ad988224bc66c34" + resolved "https://registry.npmjs.org/@lit-protocol/misc/-/misc-2.1.62.tgz" integrity sha512-i6A/kxiJQgy8BZJGH7H8V2kxqOA2xboAjH2BzAbE/pMezfHG7wybkXT9cnXnXOZsAnuGnOKd93u+j7bskuDd2w== dependencies: "@lit-protocol/constants" "2.1.62" @@ -746,12 +761,12 @@ "@lit-protocol/nacl@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/nacl/-/nacl-2.1.62.tgz#cef1e4093b5ef500a759d9b6e3b52b6d490fd750" + resolved "https://registry.npmjs.org/@lit-protocol/nacl/-/nacl-2.1.62.tgz" integrity sha512-0v9fa6Sd4xphjlYMZ9L8TTyR7G4YLvp323E8OJ76giuaPla4HXuwSiGMzUOaC6NKraArSrd54CKkHJ/bxEqVDA== "@lit-protocol/node-client@^2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/node-client/-/node-client-2.1.62.tgz#e87becc00ce45c129bdfb03e8dfbe708277bfc35" + resolved "https://registry.npmjs.org/@lit-protocol/node-client/-/node-client-2.1.62.tgz" integrity sha512-rLEUleDoJ+AATZfWNWXvy7UdSrUXMyCjpyB5bevVfk9YjIa5rd9BBXdFENCIA+9kLgVOgtND/R1PpEI/vZkMmw== dependencies: "@lit-protocol/access-control-conditions" "2.1.62" @@ -779,29 +794,29 @@ "@lit-protocol/types@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/types/-/types-2.1.62.tgz#2eeb86fd5666d92bcde7555267fd5ee7905b3033" + resolved "https://registry.npmjs.org/@lit-protocol/types/-/types-2.1.62.tgz" integrity sha512-DoIOmbI+Bg3zLWzqx4fLv1vW3k1sbDof/fxslHsLt5aX/MXHSZVKTJb+jWgNVcQ4ba+YLqgoKaPb1i58DMvCPw== "@lit-protocol/uint8arrays@2.1.62": version "2.1.62" - resolved "https://registry.yarnpkg.com/@lit-protocol/uint8arrays/-/uint8arrays-2.1.62.tgz#55d1bf7599d44e99bb6e23946fca8923d2eb1f18" + resolved "https://registry.npmjs.org/@lit-protocol/uint8arrays/-/uint8arrays-2.1.62.tgz" integrity sha512-Q9Leppzyb9Y2jwe+i8btAUkTXqgnu21PFql83v6N70dkELSC+fKBzRSRqUpFqruW7dcrG8mNWsOCQbQ0kL/w/w== "@lit/reactive-element@^1.3.0", "@lit/reactive-element@^1.6.0": version "1.6.2" - resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.6.2.tgz#c256690f82f2d7d0ffb0b1cdf68dcb1ec86cea28" + resolved "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz" integrity sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA== dependencies: "@lit-labs/ssr-dom-shim" "^1.0.0" -"@metamask/safe-event-emitter@2.0.0", "@metamask/safe-event-emitter@^2.0.0": +"@metamask/safe-event-emitter@^2.0.0", "@metamask/safe-event-emitter@2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" + resolved "https://registry.npmjs.org/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz" integrity sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q== "@metamask/utils@^3.0.1": version "3.6.0" - resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-3.6.0.tgz#b218b969a05ca7a8093b5d1670f6625061de707d" + resolved "https://registry.npmjs.org/@metamask/utils/-/utils-3.6.0.tgz" integrity sha512-9cIRrfkWvHblSiNDVXsjivqa9Ak0RYo/1H6tqTqTbAx+oBK2Sva0lWDHxGchOqA7bySGUJKAWSNJvH6gdHZ0gQ== dependencies: "@types/debug" "^4.1.7" @@ -811,7 +826,7 @@ "@motionone/animation@^10.15.1": version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.15.1.tgz#4a85596c31cbc5100ae8eb8b34c459fb0ccf6807" + resolved "https://registry.npmjs.org/@motionone/animation/-/animation-10.15.1.tgz" integrity sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ== dependencies: "@motionone/easing" "^10.15.1" @@ -819,9 +834,9 @@ "@motionone/utils" "^10.15.1" tslib "^2.3.1" -"@motionone/dom@^10.16.2": +"@motionone/dom@^10.15.5", "@motionone/dom@^10.16.2": version "10.16.2" - resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.16.2.tgz#0c44df8ee3d1cfc50ee11d27050b27824355a61a" + resolved "https://registry.npmjs.org/@motionone/dom/-/dom-10.16.2.tgz" integrity sha512-bnuHdNbge1FutZXv+k7xub9oPWcF0hsu8y1HTH/qg6av58YI0VufZ3ngfC7p2xhMJMnoh0LXFma2EGTgPeCkeg== dependencies: "@motionone/animation" "^10.15.1" @@ -833,7 +848,7 @@ "@motionone/easing@^10.15.1": version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.15.1.tgz#95cf3adaef34da6deebb83940d8143ede3deb693" + resolved "https://registry.npmjs.org/@motionone/easing/-/easing-10.15.1.tgz" integrity sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw== dependencies: "@motionone/utils" "^10.15.1" @@ -841,16 +856,16 @@ "@motionone/generators@^10.15.1": version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.15.1.tgz#dc6abb11139d1bafe758a41c134d4c753a9b871c" + resolved "https://registry.npmjs.org/@motionone/generators/-/generators-10.15.1.tgz" integrity sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ== dependencies: "@motionone/types" "^10.15.1" "@motionone/utils" "^10.15.1" tslib "^2.3.1" -"@motionone/svelte@^10.16.2": +"@motionone/svelte@^10.15.5": version "10.16.2" - resolved "https://registry.yarnpkg.com/@motionone/svelte/-/svelte-10.16.2.tgz#0b37c3b12927814d31d24941d1ca0ff49981b444" + resolved "https://registry.npmjs.org/@motionone/svelte/-/svelte-10.16.2.tgz" integrity sha512-38xsroKrfK+aHYhuQlE6eFcGy0EwrB43Q7RGjF73j/kRUTcLNu/LAaKiLLsN5lyqVzCgTBVt4TMT/ShWbTbc5Q== dependencies: "@motionone/dom" "^10.16.2" @@ -858,111 +873,76 @@ "@motionone/types@^10.15.1": version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.15.1.tgz#89441b54285012795cbba8612cbaa0fa420db3eb" + resolved "https://registry.npmjs.org/@motionone/types/-/types-10.15.1.tgz" integrity sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA== "@motionone/utils@^10.15.1": version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.15.1.tgz#6b5f51bde75be88b5411e084310299050368a438" + resolved "https://registry.npmjs.org/@motionone/utils/-/utils-10.15.1.tgz" integrity sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw== dependencies: "@motionone/types" "^10.15.1" hey-listen "^1.0.8" tslib "^2.3.1" -"@motionone/vue@^10.16.2": +"@motionone/vue@^10.15.5": version "10.16.2" - resolved "https://registry.yarnpkg.com/@motionone/vue/-/vue-10.16.2.tgz#faf13afc27620a2df870c71c58a04ee8de8dea65" + resolved "https://registry.npmjs.org/@motionone/vue/-/vue-10.16.2.tgz" integrity sha512-7/dEK/nWQXOkJ70bqb2KyNfSWbNvWqKKq1C8juj+0Mg/AorgD8O5wE3naddK0G+aXuNMqRuc4jlsYHHWHtIzVw== dependencies: "@motionone/dom" "^10.16.2" tslib "^2.3.1" -"@next/env@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/env/-/env-13.4.4.tgz#46b620f6bef97fe67a1566bf570dbb791d40c50a" - integrity sha512-q/y7VZj/9YpgzDe64Zi6rY1xPizx80JjlU2BTevlajtaE3w1LqweH1gGgxou2N7hdFosXHjGrI4OUvtFXXhGLg== +"@next/env@13.4.19": + version "13.4.19" + resolved "https://registry.npmjs.org/@next/env/-/env-13.4.19.tgz" + integrity sha512-FsAT5x0jF2kkhNkKkukhsyYOrRqtSxrEhfliniIq0bwWbuXLgyt3Gv0Ml+b91XwjwArmuP7NxCiGd++GGKdNMQ== "@next/eslint-plugin-next@13.4.4": version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.4.tgz#0df2f699e61b97c65035f87f54795f799e12fead" + resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.4.tgz" integrity sha512-5jnh7q6I15efnjR/rR+/TGTc9hn53g3JTbEjAMjmeQiExKqEUgIXqrHI5zlTNlNyzCPkBB860/ctxXheZaF2Vw== dependencies: glob "7.1.7" -"@next/swc-darwin-arm64@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.4.tgz#8c14083c2478e2a9a8d140cce5900f76b75667ff" - integrity sha512-xfjgXvp4KalNUKZMHmsFxr1Ug+aGmmO6NWP0uoh4G3WFqP/mJ1xxfww0gMOeMeSq/Jyr5k7DvoZ2Pv+XOITTtw== - -"@next/swc-darwin-x64@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.4.tgz#5fe01c65c80fcb833c8789fd70f074ea99893864" - integrity sha512-ZY9Ti1hkIwJsxGus3nlubIkvYyB0gNOYxKrfsOrLEqD0I2iCX8D7w8v6QQZ2H+dDl6UT29oeEUdDUNGk4UEpfg== - -"@next/swc-linux-arm64-gnu@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.4.tgz#f2e071f38e8a6cdadf507cc5d28956f73360d064" - integrity sha512-+KZnDeMShYkpkqAvGCEDeqYTRADJXc6SY1jWXz+Uo6qWQO/Jd9CoyhTJwRSxvQA16MoYzvILkGaDqirkRNctyA== - -"@next/swc-linux-arm64-musl@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.4.tgz#23bf75c544e54562bc24ec1be036e4bd9cf89e2c" - integrity sha512-evC1twrny2XDT4uOftoubZvW3EG0zs0ZxMwEtu/dDGVRO5n5pT48S8qqEIBGBUZYu/Xx4zzpOkIxx1vpWdE+9A== - -"@next/swc-linux-x64-gnu@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.4.tgz#bd42590950a01957952206f89cf5622e7c9e4196" - integrity sha512-PX706XcCHr2FfkyhP2lpf+pX/tUvq6/ke7JYnnr0ykNdEMo+sb7cC/o91gnURh4sPYSiZJhsF2gbIqg9rciOHQ== - -"@next/swc-linux-x64-musl@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.4.tgz#907d81feb1abec3daec0ecb61e3f39b56e7aeafe" - integrity sha512-TKUUx3Ftd95JlHV6XagEnqpT204Y+IsEa3awaYIjayn0MOGjgKZMZibqarK3B1FsMSPaieJf2FEAcu9z0yT5aA== +"@next/swc-linux-x64-gnu@13.4.19": + version "13.4.19" + resolved "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.19.tgz" + integrity sha512-htwOEagMa/CXNykFFeAHHvMJeqZfNQEoQvHfsA4wgg5QqGNqD5soeCer4oGlCol6NGUxknrQO6VEustcv+Md+g== -"@next/swc-win32-arm64-msvc@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.4.tgz#1d754d2bb10bdf9907c0acc83711438697c3b5fe" - integrity sha512-FP8AadgSq4+HPtim7WBkCMGbhr5vh9FePXiWx9+YOdjwdQocwoCK5ZVC3OW8oh3TWth6iJ0AXJ/yQ1q1cwSZ3A== - -"@next/swc-win32-ia32-msvc@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.4.tgz#77b2c7f7534b675d46e46301869e08d504d23956" - integrity sha512-3WekVmtuA2MCdcAOrgrI+PuFiFURtSyyrN1I3UPtS0ckR2HtLqyqmS334Eulf15g1/bdwMteePdK363X/Y9JMg== - -"@next/swc-win32-x64-msvc@13.4.4": - version "13.4.4" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.4.tgz#faab69239f8a9d0be7cd473e65f5a07735ef7b0e" - integrity sha512-AHRITu/CrlQ+qzoqQtEMfaTu7GHaQ6bziQln/pVWpOYC1wU+Mq6VQQFlsDtMCnDztPZtppAXdvvbNS7pcfRzlw== +"@next/swc-linux-x64-musl@13.4.19": + version "13.4.19" + resolved "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.19.tgz" + integrity sha512-4Gj4vvtbK1JH8ApWTT214b3GwUh9EKKQjY41hH/t+u55Knxi/0wesMzwQRhppK6Ddalhu0TEttbiJ+wRcoEj5Q== "@noble/curves@^1.0.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz" integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== dependencies: "@noble/hashes" "1.3.1" -"@noble/hashes@1.3.1", "@noble/hashes@^1.3.0": +"@noble/hashes@^1.3.0", "@noble/hashes@1.3.1": version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -970,12 +950,12 @@ "@pedrouid/environment@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@pedrouid/environment/-/environment-1.0.1.tgz#858f0f8a057340e0b250398b75ead77d6f4342ec" + resolved "https://registry.npmjs.org/@pedrouid/environment/-/environment-1.0.1.tgz" integrity sha512-HaW78NszGzRZd9SeoI3JD11JqY+lubnaOx7Pewj5pfjqWXOEATpeKIFb9Z4t2WBUK2iryiXX3lzWwmYWgUL0Ug== "@pkgr/utils@^2.3.1": version "2.4.1" - resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.1.tgz#adf291d0357834c410ce80af16e711b56c7b1cd3" + resolved "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz" integrity sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w== dependencies: cross-spawn "^7.0.3" @@ -987,50 +967,50 @@ "@rushstack/eslint-patch@^1.1.3": version "1.3.1" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.3.1.tgz#edbb85ff95f3be41eaa70c6d6ad6d8ba0a9c7e46" + resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.1.tgz" integrity sha512-RkmuBcqiNioeeBKbgzMlOdreUkJfYaSjwgx9XDgGGpjvWgyaxWvDmZVSN9CS6LjEASadhgPv2BcFp+SeouWXXA== "@safe-global/safe-apps-provider@^0.15.2": version "0.15.2" - resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-provider/-/safe-apps-provider-0.15.2.tgz#fa5c30140134e72bb969da76b80a16c545323e3a" + resolved "https://registry.npmjs.org/@safe-global/safe-apps-provider/-/safe-apps-provider-0.15.2.tgz" integrity sha512-BaoGAuY7h6jLBL7P+M6b7hd+1QfTv8uMyNF3udhiNUwA0XwfzH2ePQB13IEV3Mn7wdcIMEEUDS5kHbtAsj60qQ== dependencies: "@safe-global/safe-apps-sdk" "7.9.0" events "^3.3.0" -"@safe-global/safe-apps-sdk@7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-sdk/-/safe-apps-sdk-7.9.0.tgz#0c79a7760470bfdaf4cce9aa5bceef56898c7037" - integrity sha512-S2EI+JL8ocSgE3uGNaDZCzKmwfhtxXZFDUP76vN0FeaY35itFMyi8F0Vhxu0XnZm3yLzJE3tp5px6GhuQFLU6w== +"@safe-global/safe-apps-sdk@^7.9.0": + version "7.11.0" + resolved "https://registry.npmjs.org/@safe-global/safe-apps-sdk/-/safe-apps-sdk-7.11.0.tgz" + integrity sha512-RDamzPM1Lhhiiz0O+Dn6FkFqIh47jmZX+HCV/BBnBBOSKfBJE//IGD3+02zMgojXHTikQAburdPes9qmH1SA1A== dependencies: "@safe-global/safe-gateway-typescript-sdk" "^3.5.3" ethers "^5.7.2" -"@safe-global/safe-apps-sdk@^7.9.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-sdk/-/safe-apps-sdk-7.11.0.tgz#2cbc164fb70141cdf4d3331ff222cd98a2529316" - integrity sha512-RDamzPM1Lhhiiz0O+Dn6FkFqIh47jmZX+HCV/BBnBBOSKfBJE//IGD3+02zMgojXHTikQAburdPes9qmH1SA1A== +"@safe-global/safe-apps-sdk@7.9.0": + version "7.9.0" + resolved "https://registry.npmjs.org/@safe-global/safe-apps-sdk/-/safe-apps-sdk-7.9.0.tgz" + integrity sha512-S2EI+JL8ocSgE3uGNaDZCzKmwfhtxXZFDUP76vN0FeaY35itFMyi8F0Vhxu0XnZm3yLzJE3tp5px6GhuQFLU6w== dependencies: "@safe-global/safe-gateway-typescript-sdk" "^3.5.3" ethers "^5.7.2" "@safe-global/safe-gateway-typescript-sdk@^3.5.3": version "3.7.3" - resolved "https://registry.yarnpkg.com/@safe-global/safe-gateway-typescript-sdk/-/safe-gateway-typescript-sdk-3.7.3.tgz#68ec7d82711e2d0f82ce2e577b1df67ba8da2bed" + resolved "https://registry.npmjs.org/@safe-global/safe-gateway-typescript-sdk/-/safe-gateway-typescript-sdk-3.7.3.tgz" integrity sha512-O6JCgXNZWG0Vv8FnOEjKfcbsP0WxGvoPJk5ufqUrsyBlHup16It6oaLnn+25nXFLBZOHI1bz8429JlqAc2t2hg== dependencies: cross-fetch "^3.1.5" "@solana/buffer-layout@^4.0.0": version "4.0.1" - resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" + resolved "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz" integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== dependencies: buffer "~6.0.3" "@solana/web3.js@^1.70.1": version "1.77.3" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.77.3.tgz#2cbeaa1dd24f8fa386ac924115be82354dfbebab" + resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.3.tgz" integrity sha512-PHaO0BdoiQRPpieC1p31wJsBaxwIOWLh8j2ocXNKX8boCQVldt26Jqm2tZE4KlrvnCIV78owPLv1pEUgqhxZ3w== dependencies: "@babel/runtime" "^7.12.5" @@ -1049,33 +1029,41 @@ rpc-websockets "^7.5.1" superstruct "^0.14.2" -"@spruceid/siwe-parser@1.1.3", "@spruceid/siwe-parser@^1.1.3": +"@spruceid/siwe-parser@^1.1.3", "@spruceid/siwe-parser@1.1.3": version "1.1.3" - resolved "https://registry.yarnpkg.com/@spruceid/siwe-parser/-/siwe-parser-1.1.3.tgz#0eebe8bbd63c6de89cb44c06b6329b00b305df65" + resolved "https://registry.npmjs.org/@spruceid/siwe-parser/-/siwe-parser-1.1.3.tgz" integrity sha512-oQ8PcwDqjGWJvLmvAF2yzd6iniiWxK0Qtz+Dw+gLD/W5zOQJiKIUXwslHOm8VB8OOOKW9vfR3dnPBhHaZDvRsw== dependencies: apg-js "^4.1.1" "@stablelib/aead@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" + resolved "https://registry.npmjs.org/@stablelib/aead/-/aead-1.0.1.tgz" integrity sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg== "@stablelib/binary@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f" + resolved "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz" integrity sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q== dependencies: "@stablelib/int" "^1.0.1" "@stablelib/bytes@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/bytes/-/bytes-1.0.1.tgz#0f4aa7b03df3080b878c7dea927d01f42d6a20d8" + resolved "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz" integrity sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ== +"@stablelib/chacha@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@stablelib/chacha/-/chacha-1.0.1.tgz" + integrity sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + "@stablelib/chacha20poly1305@1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz#de6b18e283a9cb9b7530d8767f99cde1fec4c2ee" + resolved "https://registry.npmjs.org/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz" integrity sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA== dependencies: "@stablelib/aead" "^1.0.1" @@ -1085,22 +1073,14 @@ "@stablelib/poly1305" "^1.0.1" "@stablelib/wipe" "^1.0.1" -"@stablelib/chacha@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/chacha/-/chacha-1.0.1.tgz#deccfac95083e30600c3f92803a3a1a4fa761371" - integrity sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg== - dependencies: - "@stablelib/binary" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - "@stablelib/constant-time@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/constant-time/-/constant-time-1.0.1.tgz#bde361465e1cf7b9753061b77e376b0ca4c77e35" + resolved "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz" integrity sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg== "@stablelib/ed25519@^1.0.2": version "1.0.3" - resolved "https://registry.yarnpkg.com/@stablelib/ed25519/-/ed25519-1.0.3.tgz#f8fdeb6f77114897c887bb6a3138d659d3f35996" + resolved "https://registry.npmjs.org/@stablelib/ed25519/-/ed25519-1.0.3.tgz" integrity sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg== dependencies: "@stablelib/random" "^1.0.2" @@ -1109,12 +1089,12 @@ "@stablelib/hash@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/hash/-/hash-1.0.1.tgz#3c944403ff2239fad8ebb9015e33e98444058bc5" + resolved "https://registry.npmjs.org/@stablelib/hash/-/hash-1.0.1.tgz" integrity sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg== "@stablelib/hkdf@1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/hkdf/-/hkdf-1.0.1.tgz#b4efd47fd56fb43c6a13e8775a54b354f028d98d" + resolved "https://registry.npmjs.org/@stablelib/hkdf/-/hkdf-1.0.1.tgz" integrity sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g== dependencies: "@stablelib/hash" "^1.0.1" @@ -1123,7 +1103,7 @@ "@stablelib/hmac@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/hmac/-/hmac-1.0.1.tgz#3d4c1b8cf194cb05d28155f0eed8a299620a07ec" + resolved "https://registry.npmjs.org/@stablelib/hmac/-/hmac-1.0.1.tgz" integrity sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA== dependencies: "@stablelib/constant-time" "^1.0.1" @@ -1132,19 +1112,19 @@ "@stablelib/int@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008" + resolved "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz" integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w== "@stablelib/keyagreement@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz#4612efb0a30989deb437cd352cee637ca41fc50f" + resolved "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz" integrity sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg== dependencies: "@stablelib/bytes" "^1.0.1" "@stablelib/poly1305@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/poly1305/-/poly1305-1.0.1.tgz#93bfb836c9384685d33d70080718deae4ddef1dc" + resolved "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz" integrity sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA== dependencies: "@stablelib/constant-time" "^1.0.1" @@ -1152,7 +1132,7 @@ "@stablelib/random@^1.0.1", "@stablelib/random@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.2.tgz#2dece393636489bf7e19c51229dd7900eddf742c" + resolved "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz" integrity sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w== dependencies: "@stablelib/binary" "^1.0.1" @@ -1160,7 +1140,7 @@ "@stablelib/sha256@1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/sha256/-/sha256-1.0.1.tgz#77b6675b67f9b0ea081d2e31bda4866297a3ae4f" + resolved "https://registry.npmjs.org/@stablelib/sha256/-/sha256-1.0.1.tgz" integrity sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ== dependencies: "@stablelib/binary" "^1.0.1" @@ -1169,7 +1149,7 @@ "@stablelib/sha512@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/sha512/-/sha512-1.0.1.tgz#6da700c901c2c0ceacbd3ae122a38ac57c72145f" + resolved "https://registry.npmjs.org/@stablelib/sha512/-/sha512-1.0.1.tgz" integrity sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw== dependencies: "@stablelib/binary" "^1.0.1" @@ -1178,12 +1158,12 @@ "@stablelib/wipe@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36" + resolved "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz" integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg== "@stablelib/x25519@^1.0.3": version "1.0.3" - resolved "https://registry.yarnpkg.com/@stablelib/x25519/-/x25519-1.0.3.tgz#13c8174f774ea9f3e5e42213cbf9fc68a3c7b7fd" + resolved "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.3.tgz" integrity sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw== dependencies: "@stablelib/keyagreement" "^1.0.1" @@ -1192,108 +1172,114 @@ "@swc/helpers@0.5.1": version "0.5.1" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.1.tgz#e9031491aa3f26bfcc974a67f48bd456c8a5357a" + resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz" integrity sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg== dependencies: tslib "^2.4.0" "@tanstack/query-core@4.29.11": version "4.29.11" - resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.29.11.tgz#fa338f7d6897c6be5de6d8dabd603d9b78ee48c7" + resolved "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.11.tgz" integrity sha512-8C+hF6SFAb/TlFZyS9FItgNwrw4PMa7YeX+KQYe2ZAiEz6uzg6yIr+QBzPkUwZ/L0bXvGd1sufTm3wotoz+GwQ== "@tanstack/query-persist-client-core@4.29.11": version "4.29.11" - resolved "https://registry.yarnpkg.com/@tanstack/query-persist-client-core/-/query-persist-client-core-4.29.11.tgz#96b4b83bead480eb37e024a59fd59bfd84b0545e" + resolved "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-4.29.11.tgz" integrity sha512-CSmMZchr+446r79NJ/pjD2yfjqNqFV7k8BnqOq4yTZvXsaQLEIn3tsaU45IsPgs4N7g9OBfPUPDdapSQvck2WQ== dependencies: "@tanstack/query-core" "4.29.11" -"@tanstack/query-sync-storage-persister@^4.27.1": +"@tanstack/query-sync-storage-persister@^4.14.5": version "4.29.11" - resolved "https://registry.yarnpkg.com/@tanstack/query-sync-storage-persister/-/query-sync-storage-persister-4.29.11.tgz#577ead9d08588a420a24ff0a8b77de427a2e6ca8" + resolved "https://registry.npmjs.org/@tanstack/query-sync-storage-persister/-/query-sync-storage-persister-4.29.11.tgz" integrity sha512-JP9U3m9YPkUelcE9+7D6fAEsNEp2ysKsH6qrd0WJtqsuhe5Zwr407NxaQ5uB2ow/MmhPOm8bxzMZw00Y7RagoQ== dependencies: "@tanstack/query-persist-client-core" "4.29.11" -"@tanstack/react-query-persist-client@^4.28.0": +"@tanstack/react-query-persist-client@^4.14.5": version "4.29.12" - resolved "https://registry.yarnpkg.com/@tanstack/react-query-persist-client/-/react-query-persist-client-4.29.12.tgz#a3d3dc8dc4318689b275f7329db3619b710401e1" + resolved "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-4.29.12.tgz" integrity sha512-rh6zZJB+3j8lr+YsEkVadnqmUELmqNFZQzGGsHS5col/YOjYsMe9ppqaUjIMJ2aXnFXye50sbe4KxHhSGoaNVw== dependencies: "@tanstack/query-persist-client-core" "4.29.11" -"@tanstack/react-query@^4.28.0": +"@tanstack/react-query@^4.14.5", "@tanstack/react-query@4.29.12": version "4.29.12" - resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.29.12.tgz#de111cf1d6c389b86acacfaf972302914cfa1208" + resolved "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.12.tgz" integrity sha512-zhcN6+zF6cxprxhTHQajHGlvxgK8npnp9uLe9yaWhGc6sYcPWXzyO4raL4HomUzQOPzu3jLvkriJQ7BOrDM8vA== dependencies: "@tanstack/query-core" "4.29.11" use-sync-external-store "^1.2.0" +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + "@types/connect@^3.4.33": version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== dependencies: "@types/node" "*" "@types/debug@^4.1.7": version "4.1.8" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.8.tgz#cef723a5d0a90990313faec2d1e22aee5eecb317" + resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz" integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ== dependencies: "@types/ms" "*" "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/ms@*": version "0.7.31" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== -"@types/node@*": - version "20.2.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.6.tgz#f8f4cdcf9bc74fffcb44a9e1e3f3586d583dac24" - integrity sha512-GQBWUtGoefMEOx/vu+emHEHU5aw6JdDoEtZhoBrHFPZbA/YNRFfN996XbBASEWdvmLSLyv9FKYppYGyZjCaq/g== - -"@types/node@20.2.5": +"@types/node@*", "@types/node@20.2.5": version "20.2.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.5.tgz#26d295f3570323b2837d322180dfbf1ba156fefb" + resolved "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz" integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ== "@types/node@^12.12.54": version "12.20.55" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + resolved "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== "@types/prop-types@*": version "15.7.5" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== "@types/react-dom@18.2.4": version "18.2.4" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.4.tgz#13f25bfbf4e404d26f62ac6e406591451acba9e0" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz" integrity sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw== dependencies: "@types/react" "*" -"@types/react@*": - version "18.2.10" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.10.tgz#dd47f4f4f8fa163c135b56d5f5ecdcea1330dc5c" - integrity sha512-5UTpmDa5L+PgTLXhLPNolv7/Qh+1YQuy4fsh/IahJbvtaLz2g9qX0CKsE0rBQCvn9ymt9NpvZENZwclbLKc3EQ== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/react@18.2.9": +"@types/react@*", "@types/react@18.2.9": version "18.2.9" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.9.tgz#9207f8571afdc59a9c9c30df50e8ad2591ecefaf" + resolved "https://registry.npmjs.org/@types/react/-/react-18.2.9.tgz" integrity sha512-pL3JAesUkF7PEQGxh5XOwdXGV907te6m1/Qe1ERJLgomojS6Ne790QiA7GUl434JEkFA2aAaB6qJ5z4e1zJn/w== dependencies: "@types/prop-types" "*" @@ -1302,24 +1288,24 @@ "@types/scheduler@*": version "0.16.3" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz" integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== "@types/trusted-types@^2.0.2": version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311" + resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz" integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== "@types/ws@^7.4.4": version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz" integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== dependencies: "@types/node" "*" "@typescript-eslint/parser@^5.42.0": version "5.59.9" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.9.tgz#a85c47ccdd7e285697463da15200f9a8561dd5fa" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz" integrity sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ== dependencies: "@typescript-eslint/scope-manager" "5.59.9" @@ -1329,7 +1315,7 @@ "@typescript-eslint/scope-manager@5.59.9": version "5.59.9" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz#eadce1f2733389cdb58c49770192c0f95470d2f4" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz" integrity sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ== dependencies: "@typescript-eslint/types" "5.59.9" @@ -1337,12 +1323,12 @@ "@typescript-eslint/types@5.59.9": version "5.59.9" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.9.tgz#3b4e7ae63718ce1b966e0ae620adc4099a6dcc52" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz" integrity sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw== "@typescript-eslint/typescript-estree@5.59.9": version "5.59.9" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz#6bfea844e468427b5e72034d33c9fffc9557392b" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz" integrity sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA== dependencies: "@typescript-eslint/types" "5.59.9" @@ -1355,67 +1341,68 @@ "@typescript-eslint/visitor-keys@5.59.9": version "5.59.9" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz#9f86ef8e95aca30fb5a705bb7430f95fc58b146d" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz" integrity sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q== dependencies: "@typescript-eslint/types" "5.59.9" eslint-visitor-keys "^3.3.0" -"@wagmi/chains@0.2.22": - version "0.2.22" - resolved "https://registry.yarnpkg.com/@wagmi/chains/-/chains-0.2.22.tgz#25e511e134a00742e4fbf5108613dadf876c5bd9" - integrity sha512-TdiOzJT6TO1JrztRNjTA5Quz+UmQlbvWFG8N41u9tta0boHA1JCAzGGvU6KuIcOmJfRJkKOUIt67wlbopCpVHg== +"@wagmi/chains@0.2.14": + version "0.2.14" + resolved "https://registry.npmjs.org/@wagmi/chains/-/chains-0.2.14.tgz" + integrity sha512-esWhs1sf8/J/u+54F/sUQ97iZ/zUN2rYUrLYOD35ynIJn9ZwGXeV/tkiXx/6xXDmq0VK5oe1Pe7BU/pvaURzcA== -"@wagmi/connectors@0.3.19": - version "0.3.19" - resolved "https://registry.yarnpkg.com/@wagmi/connectors/-/connectors-0.3.19.tgz#b9e9a55f8c9824116cfcdfc95666136cf431cadc" - integrity sha512-1EnVdNjP5dAfWoW8dlUDZS+Lva8MYabWK+vwzSUBeSyJcAslXInoiHLb+cz9p8oAAqXspcPLRX3XPErYav23gA== +"@wagmi/connectors@0.3.10": + version "0.3.10" + resolved "https://registry.npmjs.org/@wagmi/connectors/-/connectors-0.3.10.tgz" + integrity sha512-O9wa6N47TJtpVdBXaONxXXjiq9ahXboGbBnf6m5tb4RIirCzEY7gnsJYYd61k3TQjd9T++xKKKzDTysm37hUHg== dependencies: - "@coinbase/wallet-sdk" "^3.6.6" + "@coinbase/wallet-sdk" "^3.5.4" "@ledgerhq/connect-kit-loader" "^1.0.1" "@safe-global/safe-apps-provider" "^0.15.2" "@safe-global/safe-apps-sdk" "^7.9.0" - "@walletconnect/ethereum-provider" "2.7.2" + "@walletconnect/ethereum-provider" "2.5.2" "@walletconnect/legacy-provider" "^2.0.0" - "@web3modal/standalone" "^2.3.7" + "@web3modal/standalone" "2.2.2" abitype "^0.3.0" eventemitter3 "^4.0.7" -"@wagmi/core@0.10.11": - version "0.10.11" - resolved "https://registry.yarnpkg.com/@wagmi/core/-/core-0.10.11.tgz#cf4079b10e5efba113c09afc39c88dc2a947689c" - integrity sha512-WOmG2RG65U6i+p09/aFztFSLPCeC+CYnkPh+OXrxQ8Q3m829983sH7xUTRbFAl561lRevUHmB+XS/na+Oj2bYQ== +"@wagmi/core@>=0.9.x", "@wagmi/core@0.10.7": + version "0.10.7" + resolved "https://registry.npmjs.org/@wagmi/core/-/core-0.10.7.tgz" + integrity sha512-D12tGHPzrJPuYoknTZ8DQHpK1AqosbdSNmFXX7EOPKsSfH139PPiLU4L1ZhcS8WprnPDczOT2AN9JNvzYqjyOw== dependencies: - "@wagmi/chains" "0.2.22" - "@wagmi/connectors" "0.3.19" + "@wagmi/chains" "0.2.14" + "@wagmi/connectors" "0.3.10" abitype "^0.3.0" eventemitter3 "^4.0.7" zustand "^4.3.1" -"@walletconnect/core@2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.7.2.tgz#698eb6178eaa17c804ca0ad3176035188b9db86b" - integrity sha512-gInSwh3uLpTEkDGArfOFoOVgiXW+zkZJpGqfARVi5fhSxsnL1jYNpqO2k8KAXUPfB4MIzLyaGruiaywncLAczA== +"@walletconnect/core@2.5.2": + version "2.5.2" + resolved "https://registry.npmjs.org/@walletconnect/core/-/core-2.5.2.tgz" + integrity sha512-R0D9NKgHBpdun65q+1L49GOIGDLaIodnyb+Dq0tXGVzvXzy2lkXOlh2e9am61ixaVrUsHt7b96b318geqsuk4Q== dependencies: - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-provider" "^1.0.12" - "@walletconnect/jsonrpc-utils" "^1.0.7" - "@walletconnect/jsonrpc-ws-connection" "^1.0.11" + "@walletconnect/heartbeat" "1.2.0" + "@walletconnect/jsonrpc-provider" "1.0.10" + "@walletconnect/jsonrpc-utils" "^1.0.4" + "@walletconnect/jsonrpc-ws-connection" "1.0.10" "@walletconnect/keyvaluestorage" "^1.0.2" "@walletconnect/logger" "^2.0.1" "@walletconnect/relay-api" "^1.0.9" "@walletconnect/relay-auth" "^1.0.4" - "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/safe-json" "^1.0.1" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.7.2" - "@walletconnect/utils" "2.7.2" + "@walletconnect/types" "2.5.2" + "@walletconnect/utils" "2.5.2" events "^3.3.0" lodash.isequal "4.5.0" + pino "7.11.0" uint8arrays "^3.1.0" "@walletconnect/core@2.8.0": version "2.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.8.0.tgz#f694e1562413c4eb700f6b3a83fa7964342100c0" + resolved "https://registry.npmjs.org/@walletconnect/core/-/core-2.8.0.tgz" integrity sha512-pl7x4sq1nuU0ixA9wF2ecjDecUzIauKr7ZwC29rs9qTcmDpxgJbbOdZwaSl+dJlf1bHC87adVLf5KAkwwo9PzQ== dependencies: "@walletconnect/heartbeat" "1.2.1" @@ -1437,7 +1424,7 @@ "@walletconnect/crypto@^1.0.3": version "1.0.3" - resolved "https://registry.yarnpkg.com/@walletconnect/crypto/-/crypto-1.0.3.tgz#7b8dd4d7e2884fe3543c7c07aea425eef5ef9dd4" + resolved "https://registry.npmjs.org/@walletconnect/crypto/-/crypto-1.0.3.tgz" integrity sha512-+2jdORD7XQs76I2Odgr3wwrtyuLUXD/kprNVsjWRhhhdO9Mt6WqVzOPu0/t7OHSmgal8k7SoBQzUc5hu/8zL/g== dependencies: "@walletconnect/encoding" "^1.0.2" @@ -1449,7 +1436,7 @@ "@walletconnect/encoding@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/encoding/-/encoding-1.0.2.tgz#cb3942ad038d6a6bf01158f66773062dd25724da" + resolved "https://registry.npmjs.org/@walletconnect/encoding/-/encoding-1.0.2.tgz" integrity sha512-CrwSBrjqJ7rpGQcTL3kU+Ief+Bcuu9PH6JLOb+wM6NITX1GTxR/MfNwnQfhLKK6xpRAyj2/nM04OOH6wS8Imag== dependencies: is-typedarray "1.0.0" @@ -1458,29 +1445,14 @@ "@walletconnect/environment@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/environment/-/environment-1.0.1.tgz#1d7f82f0009ab821a2ba5ad5e5a7b8ae3b214cd7" + resolved "https://registry.npmjs.org/@walletconnect/environment/-/environment-1.0.1.tgz" integrity sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg== dependencies: tslib "1.14.1" -"@walletconnect/ethereum-provider@2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@walletconnect/ethereum-provider/-/ethereum-provider-2.7.2.tgz#261c546883131e15faa4db6dc3ba020c6388d5af" - integrity sha512-bvmutLrKKLlQ1WxKCvvX5p5YVox1D1f3Enp6hzAiZf4taN+n/M5rmwfAcLgLhp4cTAUDhl3zgtZErzDyJnvGvQ== - dependencies: - "@walletconnect/jsonrpc-http-connection" "^1.0.4" - "@walletconnect/jsonrpc-provider" "^1.0.11" - "@walletconnect/jsonrpc-types" "^1.0.2" - "@walletconnect/jsonrpc-utils" "^1.0.7" - "@walletconnect/sign-client" "2.7.2" - "@walletconnect/types" "2.7.2" - "@walletconnect/universal-provider" "2.7.2" - "@walletconnect/utils" "2.7.2" - events "^3.3.0" - "@walletconnect/ethereum-provider@^2.1.2", "@walletconnect/ethereum-provider@^2.4.7": version "2.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/ethereum-provider/-/ethereum-provider-2.8.0.tgz#15e9efa37b7c2455cd30c883f5698c89e481b163" + resolved "https://registry.npmjs.org/@walletconnect/ethereum-provider/-/ethereum-provider-2.8.0.tgz" integrity sha512-nVVJtZUpoeurFjoEPYlrUHkT3YleCpEC9YAMKJyEIB3MZZInttcGxGyi0vwFQ+trCfuX8RrdKUPQ952NvxvCvw== dependencies: "@walletconnect/jsonrpc-http-connection" "^1.0.7" @@ -1493,17 +1465,44 @@ "@walletconnect/utils" "2.8.0" events "^3.3.0" +"@walletconnect/ethereum-provider@2.5.2": + version "2.5.2" + resolved "https://registry.npmjs.org/@walletconnect/ethereum-provider/-/ethereum-provider-2.5.2.tgz" + integrity sha512-WEN85tsuHgvoiMK4KpsRsOgsKB0QLCctSwxTqyWDybBbXuJRJGWXkZ6Oma9VSmUR0MgPSjiGmOFgY4ybMlhEMA== + dependencies: + "@walletconnect/jsonrpc-http-connection" "^1.0.4" + "@walletconnect/jsonrpc-provider" "^1.0.6" + "@walletconnect/jsonrpc-types" "^1.0.2" + "@walletconnect/jsonrpc-utils" "^1.0.4" + "@walletconnect/sign-client" "2.5.2" + "@walletconnect/types" "2.5.2" + "@walletconnect/universal-provider" "2.5.2" + "@walletconnect/utils" "2.5.2" + events "^3.3.0" + "@walletconnect/events@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c" + resolved "https://registry.npmjs.org/@walletconnect/events/-/events-1.0.1.tgz" integrity sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ== dependencies: keyvaluestorage-interface "^1.0.0" tslib "1.14.1" +"@walletconnect/heartbeat@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@walletconnect/heartbeat/-/heartbeat-1.2.0.tgz" + integrity sha512-0vbzTa/ARrpmMmOD+bQMxPvFYKtOLQZObgZakrYr0aODiMOO71CmPVNV2eAqXnw9rMmcP+z91OybLeIFlwTjjA== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/time" "^1.0.2" + chai "^4.3.7" + mocha "^10.2.0" + ts-node "^10.9.1" + tslib "1.14.1" + "@walletconnect/heartbeat@1.2.1": version "1.2.1" - resolved "https://registry.yarnpkg.com/@walletconnect/heartbeat/-/heartbeat-1.2.1.tgz#afaa3a53232ae182d7c9cff41c1084472d8f32e9" + resolved "https://registry.npmjs.org/@walletconnect/heartbeat/-/heartbeat-1.2.1.tgz" integrity sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q== dependencies: "@walletconnect/events" "^1.0.1" @@ -1512,7 +1511,7 @@ "@walletconnect/jsonrpc-http-connection@^1.0.4", "@walletconnect/jsonrpc-http-connection@^1.0.7": version "1.0.7" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-http-connection/-/jsonrpc-http-connection-1.0.7.tgz#a6973569b8854c22da707a759d241e4f5c2d5a98" + resolved "https://registry.npmjs.org/@walletconnect/jsonrpc-http-connection/-/jsonrpc-http-connection-1.0.7.tgz" integrity sha512-qlfh8fCfu8LOM9JRR9KE0s0wxP6ZG9/Jom8M0qsoIQeKF3Ni0FyV4V1qy/cc7nfI46SLQLSl4tgWSfLiE1swyQ== dependencies: "@walletconnect/jsonrpc-utils" "^1.0.6" @@ -1520,26 +1519,35 @@ cross-fetch "^3.1.4" tslib "1.14.1" -"@walletconnect/jsonrpc-provider@1.0.13", "@walletconnect/jsonrpc-provider@^1.0.11", "@walletconnect/jsonrpc-provider@^1.0.12", "@walletconnect/jsonrpc-provider@^1.0.13", "@walletconnect/jsonrpc-provider@^1.0.6": +"@walletconnect/jsonrpc-provider@^1.0.13", "@walletconnect/jsonrpc-provider@^1.0.6", "@walletconnect/jsonrpc-provider@1.0.13": version "1.0.13" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.13.tgz#9a74da648d015e1fffc745f0c7d629457f53648b" + resolved "https://registry.npmjs.org/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.13.tgz" integrity sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g== dependencies: "@walletconnect/jsonrpc-utils" "^1.0.8" "@walletconnect/safe-json" "^1.0.2" tslib "1.14.1" -"@walletconnect/jsonrpc-types@1.0.3", "@walletconnect/jsonrpc-types@^1.0.2", "@walletconnect/jsonrpc-types@^1.0.3": +"@walletconnect/jsonrpc-provider@1.0.10": + version "1.0.10" + resolved "https://registry.npmjs.org/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.10.tgz" + integrity sha512-g0ffPSpY3P6GqGjWGHsr3yqvQUhj7q2k6pAikoXv5XTXWaJRzFvrlbFkSgxziXsBrwrMZn0qvPufvpN4mMZ5FA== + dependencies: + "@walletconnect/jsonrpc-utils" "^1.0.6" + "@walletconnect/safe-json" "^1.0.1" + tslib "1.14.1" + +"@walletconnect/jsonrpc-types@^1.0.2", "@walletconnect/jsonrpc-types@^1.0.3", "@walletconnect/jsonrpc-types@1.0.3": version "1.0.3" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.3.tgz#65e3b77046f1a7fa8347ae02bc1b841abe6f290c" + resolved "https://registry.npmjs.org/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.3.tgz" integrity sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw== dependencies: keyvaluestorage-interface "^1.0.0" tslib "1.14.1" -"@walletconnect/jsonrpc-utils@1.0.8", "@walletconnect/jsonrpc-utils@^1.0.4", "@walletconnect/jsonrpc-utils@^1.0.6", "@walletconnect/jsonrpc-utils@^1.0.7", "@walletconnect/jsonrpc-utils@^1.0.8": +"@walletconnect/jsonrpc-utils@^1.0.4", "@walletconnect/jsonrpc-utils@^1.0.6", "@walletconnect/jsonrpc-utils@^1.0.7", "@walletconnect/jsonrpc-utils@^1.0.8", "@walletconnect/jsonrpc-utils@1.0.8": version "1.0.8" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.8.tgz#82d0cc6a5d6ff0ecc277cb35f71402c91ad48d72" + resolved "https://registry.npmjs.org/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.8.tgz" integrity sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw== dependencies: "@walletconnect/environment" "^1.0.1" @@ -1548,7 +1556,7 @@ "@walletconnect/jsonrpc-ws-connection@^1.0.11": version "1.0.11" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.11.tgz#1ce59d86f273d576ca73385961303ebd44dd923f" + resolved "https://registry.npmjs.org/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.11.tgz" integrity sha512-TiFJ6saasKXD+PwGkm5ZGSw0837nc6EeFmurSPgIT/NofnOV4Tv7CVJqGQN0rQYoJUSYu21cwHNYaFkzNpUN+w== dependencies: "@walletconnect/jsonrpc-utils" "^1.0.6" @@ -1557,9 +1565,20 @@ tslib "1.14.1" ws "^7.5.1" +"@walletconnect/jsonrpc-ws-connection@1.0.10": + version "1.0.10" + resolved "https://registry.npmjs.org/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.10.tgz" + integrity sha512-/tidvjfCXZuYugjF5fOswsNDPoMo9QRML3DFQ0dfNUarL4f5HGqu8NDGerr2n0+4MOX23GsT6Vv2POSwFbvgGw== + dependencies: + "@walletconnect/jsonrpc-utils" "^1.0.6" + "@walletconnect/safe-json" "^1.0.1" + events "^3.3.0" + tslib "1.14.1" + ws "^7.5.1" + "@walletconnect/keyvaluestorage@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.0.2.tgz#92f5ca0f54c1a88a093778842ce0c874d86369c8" + resolved "https://registry.npmjs.org/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.0.2.tgz" integrity sha512-U/nNG+VLWoPFdwwKx0oliT4ziKQCEoQ27L5Hhw8YOFGA2Po9A9pULUYNWhDgHkrb0gYDNt//X7wABcEWWBd3FQ== dependencies: safe-json-utils "^1.1.1" @@ -1567,7 +1586,7 @@ "@walletconnect/legacy-client@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@walletconnect/legacy-client/-/legacy-client-2.0.0.tgz#9f2c09694789fd4b6c5d68d6423b44bac55aed30" + resolved "https://registry.npmjs.org/@walletconnect/legacy-client/-/legacy-client-2.0.0.tgz" integrity sha512-v5L7rYk9loVnfvUf0mF+76bUPFaU5/Vh7mzL6/950CD/yoGdzYZ3Kj+L7mkC6HPMEGeQsBP1+sqBuiVGZ/aODA== dependencies: "@walletconnect/crypto" "^1.0.3" @@ -1583,7 +1602,7 @@ "@walletconnect/legacy-modal@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@walletconnect/legacy-modal/-/legacy-modal-2.0.0.tgz#d0fab01a1337a8f5d88cdb1430cbef2d46072bbf" + resolved "https://registry.npmjs.org/@walletconnect/legacy-modal/-/legacy-modal-2.0.0.tgz" integrity sha512-jckNd8lMhm4X7dX9TDdxM3bXKJnaqkRs6K2Mo5j6GmbIF9Eyx40jZ5+q457RVxvM6ciZEDT5s1wBHWdWoOo+9Q== dependencies: "@walletconnect/legacy-types" "^2.0.0" @@ -1594,7 +1613,7 @@ "@walletconnect/legacy-provider@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@walletconnect/legacy-provider/-/legacy-provider-2.0.0.tgz#08e2db1e4c234743b2f30422bc8100bc42e8fc44" + resolved "https://registry.npmjs.org/@walletconnect/legacy-provider/-/legacy-provider-2.0.0.tgz" integrity sha512-A8xPebMI1A+50HbWwTpFCbwP7G+1NGKdTKyg8BUUg3h3Y9JucpC1W6w/x0v1Xw7qFEqQnz74LoIN/A3ytH9xrQ== dependencies: "@walletconnect/jsonrpc-http-connection" "^1.0.4" @@ -1606,14 +1625,14 @@ "@walletconnect/legacy-types@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@walletconnect/legacy-types/-/legacy-types-2.0.0.tgz#224278ae2874c6a2ca805c2d1d062a511dcf7227" + resolved "https://registry.npmjs.org/@walletconnect/legacy-types/-/legacy-types-2.0.0.tgz" integrity sha512-sOVrA7HUdbI1OwKyPOQU0/DdvTSVFlsXWpAk2K2WvP2erTkBWPMTJq6cv2BmKdoJ3p6gLApT7sd+jHi3OF71uw== dependencies: "@walletconnect/jsonrpc-types" "^1.0.2" "@walletconnect/legacy-utils@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@walletconnect/legacy-utils/-/legacy-utils-2.0.0.tgz#e3a637c00783f9cd2ae139b640f82223ab78ed9d" + resolved "https://registry.npmjs.org/@walletconnect/legacy-utils/-/legacy-utils-2.0.0.tgz" integrity sha512-CPWxSVVXw0kgNCxvU126g4GiV3mzXmC8IPJ15twE46aJ1FX+RHEIfAzFMFz2F2+fEhBxL63A7dwNQKDXorRPcQ== dependencies: "@walletconnect/encoding" "^1.0.2" @@ -1627,7 +1646,7 @@ "@walletconnect/logger@^2.0.1": version "2.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/logger/-/logger-2.0.1.tgz#7f489b96e9a1ff6bf3e58f0fbd6d69718bf844a8" + resolved "https://registry.npmjs.org/@walletconnect/logger/-/logger-2.0.1.tgz" integrity sha512-SsTKdsgWm+oDTBeNE/zHxxr5eJfZmE9/5yp/Ku+zJtcTAjELb3DXueWkDXmE9h8uHIbJzIb5wj5lPdzyrjT6hQ== dependencies: pino "7.11.0" @@ -1635,7 +1654,7 @@ "@walletconnect/randombytes@^1.0.3": version "1.0.3" - resolved "https://registry.yarnpkg.com/@walletconnect/randombytes/-/randombytes-1.0.3.tgz#e795e4918367fd1e6a2215e075e64ab93e23985b" + resolved "https://registry.npmjs.org/@walletconnect/randombytes/-/randombytes-1.0.3.tgz" integrity sha512-35lpzxcHFbTN3ABefC9W+uBpNZl1GC4Wpx0ed30gibfO/y9oLdy1NznbV96HARQKSBV9J9M/rrtIvf6a23jfYw== dependencies: "@walletconnect/encoding" "^1.0.2" @@ -1645,7 +1664,7 @@ "@walletconnect/relay-api@^1.0.9": version "1.0.9" - resolved "https://registry.yarnpkg.com/@walletconnect/relay-api/-/relay-api-1.0.9.tgz#f8c2c3993dddaa9f33ed42197fc9bfebd790ecaf" + resolved "https://registry.npmjs.org/@walletconnect/relay-api/-/relay-api-1.0.9.tgz" integrity sha512-Q3+rylJOqRkO1D9Su0DPE3mmznbAalYapJ9qmzDgK28mYF9alcP3UwG/og5V7l7CFOqzCLi7B8BvcBUrpDj0Rg== dependencies: "@walletconnect/jsonrpc-types" "^1.0.2" @@ -1653,7 +1672,7 @@ "@walletconnect/relay-auth@^1.0.4": version "1.0.4" - resolved "https://registry.yarnpkg.com/@walletconnect/relay-auth/-/relay-auth-1.0.4.tgz#0b5c55c9aa3b0ef61f526ce679f3ff8a5c4c2c7c" + resolved "https://registry.npmjs.org/@walletconnect/relay-auth/-/relay-auth-1.0.4.tgz" integrity sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ== dependencies: "@stablelib/ed25519" "^1.0.2" @@ -1665,29 +1684,30 @@ "@walletconnect/safe-json@^1.0.1", "@walletconnect/safe-json@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.2.tgz#7237e5ca48046e4476154e503c6d3c914126fa77" + resolved "https://registry.npmjs.org/@walletconnect/safe-json/-/safe-json-1.0.2.tgz" integrity sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA== dependencies: tslib "1.14.1" -"@walletconnect/sign-client@2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.7.2.tgz#8ece418fb4995a366c0d097dd04f29b95256ae52" - integrity sha512-JOYPmrgR4YG4M2comNcXaa8cLIws0ZJj/SCpF0XJzRZP2+OXWouK19UaI32ROQrcwNodBNeYFRfT5hSM5xjfKg== +"@walletconnect/sign-client@2.5.2": + version "2.5.2" + resolved "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.5.2.tgz" + integrity sha512-eKUnGCVgYqN+6b4gm27ML/064m0c/2hTlTHy6tbUszYtEPTzb+q4fvpnWs6blaOjzc18l8NFwX3c1+MHxVdQUQ== dependencies: - "@walletconnect/core" "2.7.2" + "@walletconnect/core" "2.5.2" "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-utils" "^1.0.7" + "@walletconnect/heartbeat" "1.2.0" + "@walletconnect/jsonrpc-utils" "^1.0.4" "@walletconnect/logger" "^2.0.1" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.7.2" - "@walletconnect/utils" "2.7.2" + "@walletconnect/types" "2.5.2" + "@walletconnect/utils" "2.5.2" events "^3.3.0" + pino "7.11.0" "@walletconnect/sign-client@2.8.0": version "2.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.8.0.tgz#735dc8bf120242584fb2ff22c6a3d672c1fae1a1" + resolved "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.8.0.tgz" integrity sha512-+l9qwvVeUGk0fBQsgx6yb6hdGYt8uQ3a9jR9GgsJvm8FjFh1oUzTKqFnG7XdhCBnzFnbSoLr41Xe8PbN8qoUSw== dependencies: "@walletconnect/core" "2.8.0" @@ -1702,18 +1722,18 @@ "@walletconnect/time@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" + resolved "https://registry.npmjs.org/@walletconnect/time/-/time-1.0.2.tgz" integrity sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g== dependencies: tslib "1.14.1" -"@walletconnect/types@2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.7.2.tgz#508d1755110864dee294f955e09b7da3f8ee0064" - integrity sha512-1O2UefakZpT0ErRfEAXY7Ls3qdUrKDky/DsK088xR6klyfkQOx+aSVH0fJYLhmnqPTuvp3lrqNbsDc0s6/6nvg== +"@walletconnect/types@2.5.2": + version "2.5.2" + resolved "https://registry.npmjs.org/@walletconnect/types/-/types-2.5.2.tgz" + integrity sha512-VnV43qs4f2hwv6wGQ9ZSE+smP0z2oVy2XaVO5Szd2fmOx9bB+ov+sQzh9xeoQ+DhjNrbJhUaecW/peE6CPPSag== dependencies: "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/heartbeat" "1.2.0" "@walletconnect/jsonrpc-types" "^1.0.2" "@walletconnect/keyvaluestorage" "^1.0.2" "@walletconnect/logger" "^2.0.1" @@ -1721,7 +1741,7 @@ "@walletconnect/types@2.8.0": version "2.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.8.0.tgz#f8a5f09ee2b31abed231966e7e1eebd22be058a2" + resolved "https://registry.npmjs.org/@walletconnect/types/-/types-2.8.0.tgz" integrity sha512-FMeGK3lGXFDwcs5duoN74xL1aLrkgYqnavWE0DnFPt2i1QmSUITU9c8f88EDh8uPXANd2WIYOItm0DVCNxLGGA== dependencies: "@walletconnect/events" "^1.0.1" @@ -1731,25 +1751,26 @@ "@walletconnect/logger" "^2.0.1" events "^3.3.0" -"@walletconnect/universal-provider@2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.7.2.tgz#c3ba1ddb9a9471c15dd49c0d62fec8c6ffc48cce" - integrity sha512-5glu7vCmq3SFUYgniICf7CUZMwrd6FNS/qnCjrnfgW8T55Opms9YkhRpWTJFHpBdNRWF7n6z/Kss2J8olKTxKw== +"@walletconnect/universal-provider@2.5.2": + version "2.5.2" + resolved "https://registry.npmjs.org/@walletconnect/universal-provider/-/universal-provider-2.5.2.tgz" + integrity sha512-R61VL02zvcljwSC+FJVzxGswbN21tokQLG0IQL1tVq30+KfkZOt0y/UxsDNvgHNGleGgfoQZzOWsfSLgp5pcBQ== dependencies: "@walletconnect/jsonrpc-http-connection" "^1.0.4" - "@walletconnect/jsonrpc-provider" "^1.0.11" + "@walletconnect/jsonrpc-provider" "^1.0.6" "@walletconnect/jsonrpc-types" "^1.0.2" - "@walletconnect/jsonrpc-utils" "^1.0.7" + "@walletconnect/jsonrpc-utils" "^1.0.4" "@walletconnect/logger" "^2.0.1" - "@walletconnect/sign-client" "2.7.2" - "@walletconnect/types" "2.7.2" - "@walletconnect/utils" "2.7.2" + "@walletconnect/sign-client" "2.5.2" + "@walletconnect/types" "2.5.2" + "@walletconnect/utils" "2.5.2" eip1193-provider "1.0.1" events "^3.3.0" + pino "7.11.0" "@walletconnect/universal-provider@2.8.0": version "2.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.8.0.tgz#134f6873742f672c2424969335f9cc75d1532d17" + resolved "https://registry.npmjs.org/@walletconnect/universal-provider/-/universal-provider-2.8.0.tgz" integrity sha512-BMsGiINI3rT7DRyDJM7miuWG6vDVE0PV6zMcCXIMDYYPay7zFvJxv2VHEx9an4MutrvQR76NTRyG//i1K84VOQ== dependencies: "@walletconnect/jsonrpc-http-connection" "^1.0.7" @@ -1763,30 +1784,30 @@ eip1193-provider "1.0.1" events "^3.3.0" -"@walletconnect/utils@2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.7.2.tgz#71f2b9941a0592e155db9c7898a2e6a99f4c9a8d" - integrity sha512-b2lU/JoWqwCOLMudPSRTt3pliBnv6qQHCBWiMBYi1vL14AW3usO5QmK1wF90AVwpdPJ7wFZ6MgHymeWWfhYnGQ== +"@walletconnect/utils@2.5.2": + version "2.5.2" + resolved "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.5.2.tgz" + integrity sha512-s5bpY5q/RaXMc6LgPp+E7qPbKhrff9TjrLRjN2m9COnt9cERowpQEFrPzWmh10FatRZ7dNrudJ5I/c36nFc+hw== dependencies: "@stablelib/chacha20poly1305" "1.0.1" "@stablelib/hkdf" "1.0.1" "@stablelib/random" "^1.0.2" "@stablelib/sha256" "1.0.1" "@stablelib/x25519" "^1.0.3" - "@walletconnect/jsonrpc-utils" "^1.0.7" + "@walletconnect/jsonrpc-utils" "^1.0.4" "@walletconnect/relay-api" "^1.0.9" - "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/safe-json" "^1.0.1" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.7.2" + "@walletconnect/types" "2.5.2" "@walletconnect/window-getters" "^1.0.1" "@walletconnect/window-metadata" "^1.0.1" detect-browser "5.3.0" - query-string "7.1.3" + query-string "7.1.1" uint8arrays "^3.1.0" "@walletconnect/utils@2.8.0": version "2.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.8.0.tgz#c219e78fd2c35062cf3e37f84961afde8da9b9a1" + resolved "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.8.0.tgz" integrity sha512-Q8OwMtUevIn1+64LXyTMLlhH58k3UOAjU5b3smYZ7CEEmwEGpOTfTDAWrB3v+ZDIhjyqP94+8fuvKIbcVLKLWA== dependencies: "@stablelib/chacha20poly1305" "1.0.1" @@ -1806,109 +1827,106 @@ "@walletconnect/window-getters@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/window-getters/-/window-getters-1.0.1.tgz#f36d1c72558a7f6b87ecc4451fc8bd44f63cbbdc" + resolved "https://registry.npmjs.org/@walletconnect/window-getters/-/window-getters-1.0.1.tgz" integrity sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q== dependencies: tslib "1.14.1" "@walletconnect/window-metadata@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/window-metadata/-/window-metadata-1.0.1.tgz#2124f75447b7e989e4e4e1581d55d25bc75f7be5" + resolved "https://registry.npmjs.org/@walletconnect/window-metadata/-/window-metadata-1.0.1.tgz" integrity sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA== dependencies: "@walletconnect/window-getters" "^1.0.1" tslib "1.14.1" -"@web3modal/core@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@web3modal/core/-/core-2.4.3.tgz#ea6d3911e52a132c70defb7584f869d09a8af974" - integrity sha512-7Z/sDe9RIYQ2k9ITcxgEa/u7FvlI76vcVVZn9UY4ISivefqrH4JAS3GX4JmVNUUlovwuiZdyqBv4llAQOMK6Rg== +"@web3modal/core@2.2.2": + version "2.2.2" + resolved "https://registry.npmjs.org/@web3modal/core/-/core-2.2.2.tgz" + integrity sha512-RKbYNIEVP5Hwiva68PWXExbkTFLUTasneyRpcjoQSM4BIh78qXp1YMt0nyTvFdHmHQEGxXEMCuRG5qoE97uMHA== dependencies: buffer "6.0.3" - valtio "1.10.5" + valtio "1.10.3" -"@web3modal/standalone@^2.3.7": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@web3modal/standalone/-/standalone-2.4.3.tgz#98aaa65eba725c34d5be9078ef04b4e9b769d0f3" - integrity sha512-5ATXBoa4GGm+TIUSsKWsfWCJunv1XevOizpgTFhqyeGgRDmWhqsz9UIPzH/1mk+g0iJ/xqMKs5F6v9D2QeKxag== +"@web3modal/standalone@>=2", "@web3modal/standalone@2.2.2": + version "2.2.2" + resolved "https://registry.npmjs.org/@web3modal/standalone/-/standalone-2.2.2.tgz" + integrity sha512-c05kkTFNGZqnjJ3n2C8uo+wWL6ut1jexGYAyTvbweDengdsOr8LDo0VpK5V3XSKCV2fFcPh5JE9H1aA4jpnZPg== dependencies: - "@web3modal/core" "2.4.3" - "@web3modal/ui" "2.4.3" + "@web3modal/core" "2.2.2" + "@web3modal/ui" "2.2.2" -"@web3modal/ui@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@web3modal/ui/-/ui-2.4.3.tgz#986c6bed528dccab679c734ff531e42f6605c5b2" - integrity sha512-J989p8CdtEhI9gZHf/rZ/WFqYlrAHWw9GmAhFoiNODwjAp0BoG/uoaPiijJMchXdngihZOjLGCQwDXU16DHiKg== +"@web3modal/ui@2.2.2": + version "2.2.2" + resolved "https://registry.npmjs.org/@web3modal/ui/-/ui-2.2.2.tgz" + integrity sha512-PAuMOuk4sZ4UGjucGMZKzu6Qu56XtFsgLaqOn8ZgP2RkZmYEBGSG9mUQVzJd3XzfzAy1T91Wmqp/3TI3m0pXuQ== dependencies: - "@web3modal/core" "2.4.3" - lit "2.7.5" - motion "10.16.2" - qrcode "1.5.3" + "@web3modal/core" "2.2.2" + lit "2.6.1" + motion "10.15.5" + qrcode "1.5.1" "@wry/context@^0.7.0": version "0.7.3" - resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.7.3.tgz#240f6dfd4db5ef54f81f6597f6714e58d4f476a1" + resolved "https://registry.npmjs.org/@wry/context/-/context-0.7.3.tgz" integrity sha512-Nl8WTesHp89RF803Se9X3IiHjdmLBrIvPMaJkl+rKVJAYyPsz1TEUbu89943HpvujtSJgDUx9W4vZw3K1Mr3sA== dependencies: tslib "^2.3.0" "@wry/equality@^0.5.0": version "0.5.6" - resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.6.tgz#cd4a533c72c3752993ab8cbf682d3d20e3cb601e" + resolved "https://registry.npmjs.org/@wry/equality/-/equality-0.5.6.tgz" integrity sha512-D46sfMTngaYlrH+OspKf8mIJETntFnf6Hsjb0V41jAXJ7Bx2kB8Rv8RCUujuVWYttFtHkUNp7g+FwxNQAr6mXA== dependencies: tslib "^2.3.0" "@wry/trie@^0.3.0": version "0.3.2" - resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.3.2.tgz#a06f235dc184bd26396ba456711f69f8c35097e6" + resolved "https://registry.npmjs.org/@wry/trie/-/trie-0.3.2.tgz" integrity sha512-yRTyhWSls2OY/pYLfwff867r8ekooZ4UI+/gxot5Wj8EFwSf2rG+n+Mo/6LoLQm1TKA4GRj2+LCpbfS937dClQ== dependencies: tslib "^2.3.0" "@wry/trie@^0.4.0": version "0.4.3" - resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.4.3.tgz#077d52c22365871bf3ffcbab8e95cb8bc5689af4" + resolved "https://registry.npmjs.org/@wry/trie/-/trie-0.4.3.tgz" integrity sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w== dependencies: tslib "^2.3.0" -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - abitype@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.3.0.tgz#75150e337d88cc0b2423ed0d3fc36935f139d04c" + resolved "https://registry.npmjs.org/abitype/-/abitype-0.3.0.tgz" integrity sha512-0YokyAV4hKMcy97Pl+6QgZBlBdZJN2llslOs7kiFY+cu7kMlVXDBpxMExfv0krzBCQt2t7hNovpQ3y/zvEm18A== acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.8.0: +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.4.1, acorn@^8.8.0: version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== - aes-js@^3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" + resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz" integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz" + integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== + agentkeepalive@^4.2.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.3.0.tgz#bb999ff07412653c1803b3ced35e50729830a255" + resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz" integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg== dependencies: debug "^4.1.0" @@ -1917,7 +1935,7 @@ agentkeepalive@^4.2.1: ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -1925,26 +1943,31 @@ ajv@^6.10.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" any-promise@^1.0.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz" integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== anymatch@~3.1.2: version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" @@ -1952,29 +1975,34 @@ anymatch@~3.1.2: apg-js@^4.1.1: version "4.1.3" - resolved "https://registry.yarnpkg.com/apg-js/-/apg-js-4.1.3.tgz#0cb9dc99f8830740d7a8f9fc0048fa618ae4d199" + resolved "https://registry.npmjs.org/apg-js/-/apg-js-4.1.3.tgz" integrity sha512-XYyDcoBho8OpnWPRnedMwyL+76ovCtsESerHZEfY39dO4IrEqN97mdEYkOyHa0XTX5+3+U5FmpqPLttK0f7n6g== +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + arg@^5.0.2: version "5.0.2" - resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== aria-query@^5.1.3: version "5.1.3" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== dependencies: deep-equal "^2.0.5" array-buffer-byte-length@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + 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== dependencies: call-bind "^1.0.2" @@ -1982,7 +2010,7 @@ array-buffer-byte-length@^1.0.0: array-includes@^3.1.5, array-includes@^3.1.6: version "3.1.6" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz" integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== dependencies: call-bind "^1.0.2" @@ -1993,12 +2021,12 @@ array-includes@^3.1.5, array-includes@^3.1.6: array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array.prototype.flat@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz" integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== dependencies: call-bind "^1.0.2" @@ -2008,7 +2036,7 @@ array.prototype.flat@^1.3.1: array.prototype.flatmap@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz" integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== dependencies: call-bind "^1.0.2" @@ -2018,7 +2046,7 @@ array.prototype.flatmap@^1.3.1: array.prototype.tosorted@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz#ccf44738aa2b5ac56578ffda97c03fd3e23dd532" + resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz" integrity sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ== dependencies: call-bind "^1.0.2" @@ -2027,26 +2055,31 @@ array.prototype.tosorted@^1.1.1: es-shim-unscopables "^1.0.0" get-intrinsic "^1.1.3" +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + ast-types-flow@^0.0.7: version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== async-mutex@^0.2.6: version "0.2.6" - resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.2.6.tgz#0d7a3deb978bc2b984d5908a2038e1ae2e54ff40" + resolved "https://registry.npmjs.org/async-mutex/-/async-mutex-0.2.6.tgz" integrity sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw== dependencies: tslib "^2.0.0" atomic-sleep@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + resolved "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== autoprefixer@10.4.14: version "10.4.14" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz" integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== dependencies: browserslist "^4.21.5" @@ -2058,92 +2091,92 @@ autoprefixer@10.4.14: available-typed-arrays@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== axe-core@^4.6.2: version "4.7.2" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.2.tgz#040a7342b20765cb18bb50b628394c21bccc17a0" + resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz" integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g== axios@^0.21.0: version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + resolved "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz" integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== dependencies: follow-redirects "^1.14.0" axobject-query@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" + resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz" integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== dependencies: deep-equal "^2.0.5" balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^3.0.2: version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + resolved "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz" integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== dependencies: safe-buffer "^5.0.1" base64-js@^1.3.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== bech32@1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + resolved "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== big-integer@^1.6.44: version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz" integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== bigint-buffer@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442" + resolved "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz" integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== dependencies: bindings "^1.3.0" binary-extensions@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bind-decorator@^1.0.11: version "1.0.11" - resolved "https://registry.yarnpkg.com/bind-decorator/-/bind-decorator-1.0.11.tgz#e41bc06a1f65dd9cec476c91c5daf3978488252f" + resolved "https://registry.npmjs.org/bind-decorator/-/bind-decorator-1.0.11.tgz" integrity sha512-yzkH0uog6Vv/vQ9+rhSKxecnqGUZHYncg7qS7voz3Q76+TAi1SGiOKk2mlOvusQnFz9Dc4BC/NMkeXu11YgjJg== bindings@^1.3.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" bn.js@^4.11.9: version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== borsh@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" + resolved "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz" integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== dependencies: bn.js "^5.2.0" @@ -2152,34 +2185,46 @@ borsh@^0.7.0: bplist-parser@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz" integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== dependencies: big-integer "^1.6.44" brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.2, braces@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" brorand@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browserslist@^4.21.5: +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserslist@^4.21.5, "browserslist@>= 4.21.0": version "4.21.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.7.tgz#e2b420947e5fb0a58e8f4668ae6e23488127e551" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.7.tgz" integrity sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA== dependencies: caniuse-lite "^1.0.30001489" @@ -2189,14 +2234,14 @@ browserslist@^4.21.5: bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + resolved "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== dependencies: base-x "^3.0.2" -buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: +buffer@^6.0.3, buffer@~6.0.3, buffer@6.0.3: version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== dependencies: base64-js "^1.3.1" @@ -2204,28 +2249,28 @@ buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: bufferutil@^4.0.1: version "4.0.7" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" + resolved "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz" integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== dependencies: node-gyp-build "^4.3.0" bundle-name@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + resolved "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz" integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== dependencies: run-applescript "^5.0.0" busboy@1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz" integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== dependencies: streamsearch "^1.1.0" call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: function-bind "^1.1.1" @@ -2233,35 +2278,58 @@ call-bind@^1.0.0, call-bind@^1.0.2: callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase-css@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== camelcase@^5.0.0: version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001489: - version "1.0.30001498" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001498.tgz#84e4ee2d03e0e4f8a04a508853b75a980c703201" - integrity sha512-LFInN2zAwx3ANrGCDZ5AKKJroHqNKyjXitdV5zRIVIaQlXKj3GmxUKagoKsjqUfckpAObPCEWnk5EeMlyMWcgw== +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -chalk@^4.0.0: +caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001489: + version "1.0.30001497" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001497.tgz" + integrity sha512-I4/duVK4wL6rAK/aKZl3HXB4g+lIZvaT4VLAn2rCgJ38jVLb0lv2Xug6QuqmxXFVRJMF74SPPWPJ/1Sdm3vCzw== + +chai@^4.3.7: + version "4.3.7" + resolved "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz" + integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^4.1.2" + get-func-name "^2.0.0" + loupe "^2.3.1" + pathval "^1.1.1" + type-detect "^4.0.5" + +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@^3.5.3: +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" + integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== + +chokidar@^3.5.3, chokidar@3.5.3: version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: anymatch "~3.1.2" @@ -2276,72 +2344,86 @@ chokidar@^3.5.3: client-only@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== cliui@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + resolved "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz" integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== dependencies: string-width "^4.2.0" strip-ansi "^6.0.0" wrap-ansi "^6.2.0" +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + clsx@^1.1.0: version "1.2.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== commander@^2.20.3: version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commander@^4.0.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== copy-to-clipboard@^3.3.3: version "3.3.3" - resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" + resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz" integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== dependencies: toggle-selection "^1.0.6" core-util-is@~1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-fetch@^3.1.4, cross-fetch@^3.1.5: version "3.1.6" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.6.tgz#bae05aa31a4da760969756318feeee6e70f15d6c" + resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz" integrity sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g== dependencies: node-fetch "^2.6.11" cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -2350,51 +2432,63 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: cssesc@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== csstype@^3.0.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz" integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== damerau-levenshtein@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" + resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== debug@^3.2.7: version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@4.3.4: version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" decamelize@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + decimal.js@^10.4.3: version "10.4.3" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== decode-uri-component@^0.2.0, decode-uri-component@^0.2.2: version "0.2.2" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== +deep-eql@^4.1.2: + version "4.1.3" + resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz" + integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== + dependencies: + type-detect "^4.0.0" + deep-equal@^2.0.5: version "2.2.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.1.tgz#c72ab22f3a7d3503a4ca87dde976fe9978816739" + resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz" integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== dependencies: array-buffer-byte-length "^1.0.0" @@ -2418,12 +2512,12 @@ deep-equal@^2.0.5: deep-is@^0.1.3: version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== default-browser-id@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + resolved "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz" integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== dependencies: bplist-parser "^0.2.0" @@ -2431,7 +2525,7 @@ default-browser-id@^3.0.0: default-browser@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + resolved "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz" integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== dependencies: bundle-name "^3.0.0" @@ -2441,12 +2535,12 @@ default-browser@^4.0.0: define-lazy-prop@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz" integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz" integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== dependencies: has-property-descriptors "^1.0.0" @@ -2454,58 +2548,68 @@ define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: delay@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + resolved "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz" integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== depd@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -detect-browser@5.3.0, detect-browser@^5.3.0: +detect-browser@^5.3.0, detect-browser@5.3.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" + resolved "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz" integrity sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w== didyoumean@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + dijkstrajs@^1.0.1: version "1.0.3" - resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz#4c8dbdea1f0f6478bff94d9c49c784d623e4fc23" + resolved "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz" integrity sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA== dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" dlv@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== doctrine@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" duplexify@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" + resolved "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz" integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== dependencies: end-of-stream "^1.4.1" @@ -2515,19 +2619,19 @@ duplexify@^4.1.2: eip1193-provider@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/eip1193-provider/-/eip1193-provider-1.0.1.tgz#420d29cf4f6c443e3f32e718fb16fafb250637c3" + resolved "https://registry.npmjs.org/eip1193-provider/-/eip1193-provider-1.0.1.tgz" integrity sha512-kSuqwQ26d7CzuS/t3yRXo2Su2cVH0QfvyKbr2H7Be7O5YDyIq4hQGCNTo5wRdP07bt+E2R/8nPCzey4ojBHf7g== dependencies: "@json-rpc-tools/provider" "^1.5.5" electron-to-chromium@^1.4.411: - version "1.4.427" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.427.tgz#67e8069f7a864fc092fe2e09f196e68af5cb88a1" - integrity sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw== + version "1.4.426" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.426.tgz" + integrity sha512-dWuNH+XUT9hdFHASfMpcZGW5kUyJvllumJkXaXiswuCkoaFIFI89aykBPuHEi1YUWQGRCqvIO0BUdmeFJ4W4Ww== elliptic@6.5.4: version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: bn.js "^4.11.9" @@ -2540,36 +2644,36 @@ elliptic@6.5.4: emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== emoji-regex@^9.2.2: version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== encode-utf8@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + resolved "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz" integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== -encoding@0.1.13: +encoding@^0.1.0, encoding@0.1.13: version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== dependencies: iconv-lite "^0.6.2" end-of-stream@^1.4.1: version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" enhanced-resolve@^5.12.0: version "5.14.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz#de684b6803724477a4af5d74ccae5de52c25f6b3" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz" integrity sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow== dependencies: graceful-fs "^4.2.4" @@ -2577,7 +2681,7 @@ enhanced-resolve@^5.12.0: es-abstract@^1.19.0, es-abstract@^1.20.4: version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz" integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== dependencies: array-buffer-byte-length "^1.0.0" @@ -2617,7 +2721,7 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: es-get-iterator@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz" integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== dependencies: call-bind "^1.0.2" @@ -2632,7 +2736,7 @@ es-get-iterator@^1.1.3: es-set-tostringtag@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz" integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== dependencies: get-intrinsic "^1.1.3" @@ -2641,14 +2745,14 @@ es-set-tostringtag@^2.0.1: es-shim-unscopables@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== dependencies: has "^1.0.3" es-to-primitive@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" @@ -2657,29 +2761,29 @@ es-to-primitive@^1.2.1: es6-promise@^4.0.3: version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== es6-promisify@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== dependencies: es6-promise "^4.0.3" escalade@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-string-regexp@^4.0.0: +escape-string-regexp@^4.0.0, escape-string-regexp@4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== eslint-config-next@13.4.4: version "13.4.4" - resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-13.4.4.tgz#95356e96f3796ad0587fa2aaa51ec4a81e71cedc" + resolved "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.4.tgz" integrity sha512-z/PMbm6L0iC/fwISULxe8IVy4DtNqZk2wQY711o35klenq70O6ns82A8yuMVCFjHC0DIyB2lyugesRtuk9u8dQ== dependencies: "@next/eslint-plugin-next" "13.4.4" @@ -2694,7 +2798,7 @@ eslint-config-next@13.4.4: eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.7: version "0.3.7" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz" integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== dependencies: debug "^3.2.7" @@ -2703,7 +2807,7 @@ eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.7: eslint-import-resolver-typescript@^3.5.2: version "3.5.5" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz#0a9034ae7ed94b254a360fbea89187b60ea7456d" + resolved "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz" integrity sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw== dependencies: debug "^4.3.4" @@ -2717,14 +2821,14 @@ eslint-import-resolver-typescript@^3.5.2: eslint-module-utils@^2.7.4: version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz" integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" -eslint-plugin-import@^2.26.0: +eslint-plugin-import@*, eslint-plugin-import@^2.26.0: version "2.27.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz" integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== dependencies: array-includes "^3.1.6" @@ -2745,7 +2849,7 @@ eslint-plugin-import@^2.26.0: eslint-plugin-jsx-a11y@^6.5.1: version "6.7.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" + resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz" integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== dependencies: "@babel/runtime" "^7.20.7" @@ -2767,12 +2871,12 @@ eslint-plugin-jsx-a11y@^6.5.1: eslint-plugin-react-hooks@^4.5.0: version "4.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" + resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz" integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== eslint-plugin-react@^7.31.7: version "7.32.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz#e71f21c7c265ebce01bcbc9d0955170c55571f10" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz" integrity sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg== dependencies: array-includes "^3.1.6" @@ -2793,7 +2897,7 @@ eslint-plugin-react@^7.31.7: eslint-scope@^7.2.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== dependencies: esrecurse "^4.3.0" @@ -2801,12 +2905,12 @@ eslint-scope@^7.2.0: eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: version "3.4.1" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== -eslint@8.42.0: +eslint@*, "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.23.0 || ^8.0.0", eslint@8.42.0: version "8.42.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.42.0.tgz#7bebdc3a55f9ed7167251fe7259f75219cade291" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz" integrity sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A== dependencies: "@eslint-community/eslint-utils" "^4.2.0" @@ -2851,7 +2955,7 @@ eslint@8.42.0: espree@^9.5.2: version "9.5.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" + resolved "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz" integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== dependencies: acorn "^8.8.0" @@ -2860,31 +2964,31 @@ espree@^9.5.2: esquery@^1.4.2: version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== eth-block-tracker@6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-6.1.0.tgz#0481f97bbb88a100b9d45806fe7e37af741cbefc" + resolved "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-6.1.0.tgz" integrity sha512-K9SY8+/xMBi4M5HHTDdxnpEqEEGjbNpzHFqvxyjMZej8InV/B+CkFRKM6W+uvrFJ7m8Zd1E0qUkseU3vdIDFYQ== dependencies: "@metamask/safe-event-emitter" "^2.0.0" @@ -2894,7 +2998,7 @@ eth-block-tracker@6.1.0: eth-json-rpc-filters@5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-5.1.0.tgz#f0c2aeaec2a45e2dc6ca1b9843d8e85447821427" + resolved "https://registry.npmjs.org/eth-json-rpc-filters/-/eth-json-rpc-filters-5.1.0.tgz" integrity sha512-fos+9xmoa1A2Ytsc9eYof17r81BjdJOUcGcgZn4K/tKdCCTb+a8ytEtwlu1op5qsXFDlgGmstTELFrDEc89qEQ== dependencies: "@metamask/safe-event-emitter" "^2.0.0" @@ -2905,29 +3009,22 @@ eth-json-rpc-filters@5.1.0: eth-query@^2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" + resolved "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz" integrity sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA== dependencies: json-rpc-random-id "^1.0.0" xtend "^4.0.1" -eth-rpc-errors@4.0.2: +eth-rpc-errors@^4.0.2, eth-rpc-errors@4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-4.0.2.tgz#11bc164e25237a679061ac05b7da7537b673d3b7" + resolved "https://registry.npmjs.org/eth-rpc-errors/-/eth-rpc-errors-4.0.2.tgz" integrity sha512-n+Re6Gu8XGyfFy1it0AwbD1x0MUzspQs0D5UiPs1fFPCr6WAwZM+vbIhXheBFrpgosqN9bs5PqlB4Q61U/QytQ== dependencies: fast-safe-stringify "^2.0.6" -eth-rpc-errors@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-4.0.3.tgz#6ddb6190a4bf360afda82790bb7d9d5e724f423a" - integrity sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg== - dependencies: - fast-safe-stringify "^2.0.6" - -ethers@^5.7.1, ethers@^5.7.2: +ethers@^5.7.1, ethers@^5.7.2, "ethers@>=5.5.1 <6", ethers@5.5.1: version "5.7.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" + resolved "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== dependencies: "@ethersproject/abi" "5.7.0" @@ -2963,17 +3060,17 @@ ethers@^5.7.1, ethers@^5.7.2: eventemitter3@^4.0.7: version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== execa@^5.0.0: version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -2988,7 +3085,7 @@ execa@^5.0.0: execa@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" + resolved "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz" integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== dependencies: cross-spawn "^7.0.3" @@ -3003,17 +3100,17 @@ execa@^7.1.1: eyes@^0.1.8: version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + resolved "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9: version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -3024,71 +3121,71 @@ fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9: fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-redact@^3.0.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.2.0.tgz#b1e2d39bc731376d28bde844454fa23e26919987" + resolved "https://registry.npmjs.org/fast-redact/-/fast-redact-3.2.0.tgz" integrity sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw== fast-safe-stringify@^2.0.6: version "2.1.1" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + resolved "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz" integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== fast-stable-stringify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" + resolved "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz" integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== fastq@^1.6.0: version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" 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" + resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" filter-obj@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + resolved "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz" integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== find-up@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" path-exists "^4.0.0" -find-up@^5.0.0: +find-up@^5.0.0, find-up@5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -3096,52 +3193,52 @@ find-up@^5.0.0: flat-cache@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: flatted "^3.1.0" rimraf "^3.0.2" +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + flatted@^3.1.0: version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== follow-redirects@^1.14.0: version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== for-each@^0.3.3: version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== dependencies: is-callable "^1.1.3" fraction.js@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: - 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: version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== function.prototype.name@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== dependencies: call-bind "^1.0.2" @@ -3151,17 +3248,22 @@ function.prototype.name@^1.1.5: functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -get-caller-file@^2.0.1: +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" + integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz" integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== dependencies: function-bind "^1.1.1" @@ -3171,12 +3273,12 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== get-symbol-description@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== dependencies: call-bind "^1.0.2" @@ -3184,29 +3286,41 @@ get-symbol-description@^1.0.0: get-tsconfig@^4.5.0: version "4.6.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.6.0.tgz#e977690993a42f3e320e932427502a40f7af6d05" + resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.0.tgz" integrity sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg== dependencies: resolve-pkg-maps "^1.0.0" -glob-parent@^5.1.2, glob-parent@~5.1.2: +glob-parent@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-parent@^6.0.2: version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.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== +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.1.3, glob@7.1.7: + version "7.1.7" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3215,10 +3329,10 @@ glob@7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== +glob@7.1.6: + version "7.1.6" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3227,35 +3341,35 @@ glob@7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== +glob@7.2.0: + version "7.2.0" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.1.1" + minimatch "^3.0.4" once "^1.3.0" path-is-absolute "^1.0.0" globals@^13.19.0: version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== dependencies: type-fest "^0.20.2" globalthis@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== dependencies: define-properties "^1.1.3" globby@^11.1.0: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -3267,7 +3381,7 @@ globby@^11.1.0: globby@^13.1.3: version "13.1.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.4.tgz#2f91c116066bcec152465ba36e5caa4a13c01317" + resolved "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz" integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== dependencies: dir-glob "^3.0.1" @@ -3278,90 +3392,95 @@ globby@^13.1.3: gopd@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.2.4: +graceful-fs@^4.1.2, graceful-fs@^4.2.4: version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== graphemer@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== graphql-tag@^2.12.6: version "2.12.6" - resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" + resolved "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz" integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== dependencies: tslib "^2.1.0" -graphql@^16.6.0: +"graphql@^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", "graphql@^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "graphql@^14.0.0 || ^15.0.0 || ^16.0.0", graphql@^16.6.0: version "16.6.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" + resolved "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz" integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-property-descriptors@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== dependencies: get-intrinsic "^1.1.1" has-proto@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== has-tostringtag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== dependencies: has-symbols "^1.0.2" has@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: +hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7, hash.js@1.1.7: version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.1" +he@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + hey-listen@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" + resolved "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz" integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== hmac-drbg@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== dependencies: hash.js "^1.0.3" @@ -3370,53 +3489,53 @@ hmac-drbg@^1.0.1: hoist-non-react-statics@^3.3.2: version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== dependencies: react-is "^16.7.0" human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== human-signals@^4.3.0: version "4.3.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz" integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== humanize-ms@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== dependencies: ms "^2.0.0" iconv-lite@^0.6.2: version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" ieee754@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^5.2.0: version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== immediate@~3.0.5: version "3.0.6" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -3424,25 +3543,25 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: +inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4, inherits@2: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== dependencies: get-intrinsic "^1.2.0" @@ -3451,7 +3570,7 @@ internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== dependencies: call-bind "^1.0.2" @@ -3459,7 +3578,7 @@ is-arguments@^1.0.4, is-arguments@^1.1.1: is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== dependencies: call-bind "^1.0.2" @@ -3468,21 +3587,21 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: is-bigint@^1.0.1: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== dependencies: has-bigints "^1.0.1" is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" @@ -3490,94 +3609,99 @@ is-boolean-object@^1.1.0: is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-core-module@^2.11.0, is-core-module@^2.9.0: version "2.12.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz" integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== dependencies: has "^1.0.3" is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== dependencies: has-tostringtag "^1.0.0" is-docker@^2.0.0: version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-docker@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz" integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-generator-function@^1.0.7: version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz" integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== dependencies: has-tostringtag "^1.0.0" is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-inside-container@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + resolved "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz" integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== dependencies: is-docker "^3.0.0" is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== is-negative-zero@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== dependencies: has-tostringtag "^1.0.0" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-path-inside@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-plain-obj@^2.1.0: + 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== + is-regex@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" @@ -3585,43 +3709,43 @@ is-regex@^1.1.4: is-set@^2.0.1, is-set@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== is-shared-array-buffer@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== dependencies: call-bind "^1.0.2" is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-stream@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz" integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== dependencies: has-tostringtag "^1.0.0" is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: has-symbols "^1.0.2" is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9: version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz" integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== dependencies: available-typed-arrays "^1.0.5" @@ -3630,26 +3754,31 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9: gopd "^1.0.1" has-tostringtag "^1.0.0" -is-typedarray@1.0.0, is-typedarray@^1.0.0: +is-typedarray@^1.0.0, is-typedarray@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-weakmap@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== is-weakref@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== dependencies: call-bind "^1.0.2" is-weakset@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== dependencies: call-bind "^1.0.2" @@ -3657,74 +3786,74 @@ is-weakset@^2.0.1: is-wsl@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== dependencies: is-docker "^2.0.0" isarray@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== isarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isomorphic-ws@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== jayson@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.1.0.tgz#60dc946a85197317f2b1439d672a8b0a99cea2f9" + resolved "https://registry.npmjs.org/jayson/-/jayson-4.1.0.tgz" integrity sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A== dependencies: "@types/connect" "^3.4.33" "@types/node" "^12.12.54" "@types/ws" "^7.4.4" - JSONStream "^1.3.5" commander "^2.20.3" delay "^5.0.0" es6-promisify "^5.0.0" eyes "^0.1.8" isomorphic-ws "^4.0.1" json-stringify-safe "^5.0.1" + JSONStream "^1.3.5" uuid "^8.3.2" ws "^7.4.5" jiti@^1.18.2: version "1.18.2" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd" + resolved "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz" integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== js-sha3@0.8.0: version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== "js-tokens@^3.0.0 || ^4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^4.1.0: +js-yaml@^4.1.0, js-yaml@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" -json-rpc-engine@6.1.0, json-rpc-engine@^6.1.0: +json-rpc-engine@^6.1.0, json-rpc-engine@6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz#bf5ff7d029e1c1bf20cb6c0e9f348dcd8be5a393" + resolved "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz" integrity sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ== dependencies: "@metamask/safe-event-emitter" "^2.0.0" @@ -3732,39 +3861,47 @@ json-rpc-engine@6.1.0, json-rpc-engine@^6.1.0: json-rpc-random-id@^1.0.0, json-rpc-random-id@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" + resolved "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz" integrity sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-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" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== 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" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== json5@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" jsonparse@^1.2.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== +JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: version "3.3.3" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz" integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== dependencies: array-includes "^3.1.5" @@ -3772,7 +3909,7 @@ jsonparse@^1.2.0: jszip@^3.10.1: version "3.10.1" - resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + resolved "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz" integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== dependencies: lie "~3.3.0" @@ -3782,12 +3919,12 @@ jszip@^3.10.1: jwt-decode@^3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" + resolved "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz" integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A== keccak@^3.0.1: version "3.0.3" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" + resolved "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz" integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== dependencies: node-addon-api "^2.0.0" @@ -3796,24 +3933,24 @@ keccak@^3.0.1: keyvaluestorage-interface@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz#13ebdf71f5284ad54be94bd1ad9ed79adad515ff" + resolved "https://registry.npmjs.org/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz" integrity sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g== language-subtag-registry@~0.3.2: version "0.3.22" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" + resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== language-tags@=1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" + resolved "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz" integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== dependencies: language-subtag-registry "~0.3.2" levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -3821,118 +3958,138 @@ levn@^0.4.1: lie@~3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + resolved "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz" integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== dependencies: immediate "~3.0.5" lilconfig@^2.0.5, lilconfig@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== lines-and-columns@^1.1.6: version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lit-connect-modal@^0.1.11: version "0.1.11" - resolved "https://registry.yarnpkg.com/lit-connect-modal/-/lit-connect-modal-0.1.11.tgz#688fa9601b920c917856a5dbe8491a4fbaf1d6ab" + resolved "https://registry.npmjs.org/lit-connect-modal/-/lit-connect-modal-0.1.11.tgz" integrity sha512-EG6pcCqdxZQJt3MPDq3gJ5Sz4E5sJdydtAF7VFJu6z6GDHO1Ybp8WrTx8CUnHiF54/MQBRi6Nb7cbTvv+BKWvQ== dependencies: micromodal "^0.4.10" -lit-element@^3.3.0: +lit-element@^3.2.0: version "3.3.2" - resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-3.3.2.tgz#9913bf220b85065f0e5f1bb8878cc44f36b50cfa" + resolved "https://registry.npmjs.org/lit-element/-/lit-element-3.3.2.tgz" integrity sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ== dependencies: "@lit-labs/ssr-dom-shim" "^1.1.0" "@lit/reactive-element" "^1.3.0" lit-html "^2.7.0" -lit-html@^2.7.0: +lit-html@^2.6.0, lit-html@^2.7.0: version "2.7.4" - resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-2.7.4.tgz#6d75001977c206683685b9d76594a516afda2954" + resolved "https://registry.npmjs.org/lit-html/-/lit-html-2.7.4.tgz" integrity sha512-/Jw+FBpeEN+z8X6PJva5n7+0MzCVAH2yypN99qHYYkq8bI+j7I39GH+68Z/MZD6rGKDK9RpzBw7CocfmHfq6+g== dependencies: "@types/trusted-types" "^2.0.2" lit-siwe@^1.1.8: version "1.1.8" - resolved "https://registry.yarnpkg.com/lit-siwe/-/lit-siwe-1.1.8.tgz#6a393069012816d629c518bb8aa410f1e4a78bd7" + resolved "https://registry.npmjs.org/lit-siwe/-/lit-siwe-1.1.8.tgz" integrity sha512-gXI8GG0GAClw6G7T9p4p6Kn9ywDo8j2d90ShaYArJdsqqO9gwXfzxF84SMeY+bpsNqqQ3FahrhEwTCHd6w7wNw== dependencies: "@spruceid/siwe-parser" "1.1.3" "@stablelib/random" "^1.0.1" apg-js "^4.1.1" -lit@2.7.5: - version "2.7.5" - resolved "https://registry.yarnpkg.com/lit/-/lit-2.7.5.tgz#60bc82990cfad169d42cd786999356dcf79b035f" - integrity sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ== +lit@2.6.1: + version "2.6.1" + resolved "https://registry.npmjs.org/lit/-/lit-2.6.1.tgz" + integrity sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw== dependencies: "@lit/reactive-element" "^1.6.0" - lit-element "^3.3.0" - lit-html "^2.7.0" + lit-element "^3.2.0" + lit-html "^2.6.0" locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" lodash.isequal@4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash@^4.17.21: version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" +loupe@^2.3.1: + version "2.3.6" + resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz" + integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== + dependencies: + get-func-name "^2.0.0" + lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: braces "^3.0.2" @@ -3940,71 +4097,105 @@ micromatch@^4.0.4, micromatch@^4.0.5: micromodal@^0.4.10: version "0.4.10" - resolved "https://registry.yarnpkg.com/micromodal/-/micromodal-0.4.10.tgz#d6f59c21d2f4a5af480f65909eb9608a1d558c73" + resolved "https://registry.npmjs.org/micromodal/-/micromodal-0.4.10.tgz" integrity sha512-BUrEnzMPFBwK8nOE4xUDYHLrlGlLULQVjpja99tpJQPSUEWgw3kTLp1n1qv0HmKU29AiHE7Y7sMLiRziDK4ghQ== mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== mimic-fn@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -motion@10.16.2: - version "10.16.2" - resolved "https://registry.yarnpkg.com/motion/-/motion-10.16.2.tgz#7dc173c6ad62210a7e9916caeeaf22c51e598d21" - integrity sha512-p+PurYqfUdcJZvtnmAqu5fJgV2kR0uLFQuBKtLeFVTrYEVllI99tiOTSefVNYuip9ELTEkepIIDftNdze76NAQ== +mocha@^10.2.0: + version "10.2.0" + resolved "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +motion@10.15.5: + version "10.15.5" + resolved "https://registry.npmjs.org/motion/-/motion-10.15.5.tgz" + integrity sha512-ejP6KioN4pigTGxL93APzOnvtLklParL59UQB2T3HWXQBxFcIp5/7YXFmkgiA6pNKKzjvnLhnonRBN5iSFMnNw== dependencies: "@motionone/animation" "^10.15.1" - "@motionone/dom" "^10.16.2" - "@motionone/svelte" "^10.16.2" + "@motionone/dom" "^10.15.5" + "@motionone/svelte" "^10.15.5" "@motionone/types" "^10.15.1" "@motionone/utils" "^10.15.1" - "@motionone/vue" "^10.16.2" + "@motionone/vue" "^10.15.5" -ms@2.1.2: +ms@^2.0.0, ms@^2.1.1, ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0, ms@^2.1.1: +ms@2.1.3: version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== multiformats@^9.4.2: version "9.9.0" - resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" + resolved "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz" integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== mz@^2.7.0: version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz" integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== dependencies: any-promise "^1.0.0" @@ -4013,101 +4204,107 @@ mz@^2.7.0: nanoid@^3.3.4, nanoid@^3.3.6: version "3.3.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -next@13.4.4: - version "13.4.4" - resolved "https://registry.yarnpkg.com/next/-/next-13.4.4.tgz#d1027c8d77f4c51be0b39f671b4820db03c93e60" - integrity sha512-C5S0ysM0Ily9McL4Jb48nOQHT1BukOWI59uC3X/xCMlYIh9rJZCv7nzG92J6e1cOBqQbKovlpgvHWFmz4eKKEA== +next@^13.4.19: + version "13.4.19" + resolved "https://registry.npmjs.org/next/-/next-13.4.19.tgz" + integrity sha512-HuPSzzAbJ1T4BD8e0bs6B9C1kWQ6gv8ykZoRWs5AQoiIuqbGHHdQO7Ljuvg05Q0Z24E2ABozHe6FxDvI6HfyAw== dependencies: - "@next/env" "13.4.4" + "@next/env" "13.4.19" "@swc/helpers" "0.5.1" busboy "1.6.0" caniuse-lite "^1.0.30001406" postcss "8.4.14" styled-jsx "5.1.1" + watchpack "2.4.0" zod "3.21.4" optionalDependencies: - "@next/swc-darwin-arm64" "13.4.4" - "@next/swc-darwin-x64" "13.4.4" - "@next/swc-linux-arm64-gnu" "13.4.4" - "@next/swc-linux-arm64-musl" "13.4.4" - "@next/swc-linux-x64-gnu" "13.4.4" - "@next/swc-linux-x64-musl" "13.4.4" - "@next/swc-win32-arm64-msvc" "13.4.4" - "@next/swc-win32-ia32-msvc" "13.4.4" - "@next/swc-win32-x64-msvc" "13.4.4" + "@next/swc-darwin-arm64" "13.4.19" + "@next/swc-darwin-x64" "13.4.19" + "@next/swc-linux-arm64-gnu" "13.4.19" + "@next/swc-linux-arm64-musl" "13.4.19" + "@next/swc-linux-x64-gnu" "13.4.19" + "@next/swc-linux-x64-musl" "13.4.19" + "@next/swc-win32-arm64-msvc" "13.4.19" + "@next/swc-win32-ia32-msvc" "13.4.19" + "@next/swc-win32-x64-msvc" "13.4.19" node-addon-api@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== node-fetch@^2.6.1, node-fetch@^2.6.11, node-fetch@^2.6.7: version "2.6.11" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz" integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== dependencies: whatwg-url "^5.0.0" node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" + resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz" integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== node-releases@^2.0.12: version "2.0.12" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz" integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-range@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" npm-run-path@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz" integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== dependencies: path-key "^4.0.0" object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-hash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== object-inspect@^1.12.3, object-inspect@^1.9.0: version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== object-is@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== dependencies: call-bind "^1.0.2" @@ -4115,12 +4312,12 @@ object-is@^1.1.5: object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object.assign@^4.1.3, object.assign@^4.1.4: version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== dependencies: call-bind "^1.0.2" @@ -4130,7 +4327,7 @@ object.assign@^4.1.3, object.assign@^4.1.4: object.entries@^1.1.6: version "1.1.6" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" + resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz" integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== dependencies: call-bind "^1.0.2" @@ -4139,7 +4336,7 @@ object.entries@^1.1.6: object.fromentries@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz" integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== dependencies: call-bind "^1.0.2" @@ -4148,7 +4345,7 @@ object.fromentries@^2.0.6: object.hasown@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92" + resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz" integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== dependencies: define-properties "^1.1.4" @@ -4156,7 +4353,7 @@ object.hasown@^1.1.2: object.values@^1.1.6: version "1.1.6" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz" integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== dependencies: call-bind "^1.0.2" @@ -4165,33 +4362,33 @@ object.values@^1.1.6: on-exit-leak-free@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" + resolved "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz" integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== once@^1.3.0, once@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" onetime@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" onetime@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + resolved "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz" integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== dependencies: mimic-fn "^4.0.0" open@^9.1.0: version "9.1.0" - resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + resolved "https://registry.npmjs.org/open/-/open-9.1.0.tgz" integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== dependencies: default-browser "^4.0.0" @@ -4201,7 +4398,7 @@ open@^9.1.0: optimism@^0.16.2: version "0.16.2" - resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.16.2.tgz#519b0c78b3b30954baed0defe5143de7776bf081" + resolved "https://registry.npmjs.org/optimism/-/optimism-0.16.2.tgz" integrity sha512-zWNbgWj+3vLEjZNIh/okkY2EUfX+vB9TJopzIZwT1xxaMqC5hRLLraePod4c5n4He08xuXNH+zhKFFCu390wiQ== dependencies: "@wry/context" "^0.7.0" @@ -4209,7 +4406,7 @@ optimism@^0.16.2: optionator@^0.9.1: version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: deep-is "^0.1.3" @@ -4221,107 +4418,112 @@ optionator@^0.9.1: p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" p-try@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.2: version "1.0.11" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-key@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + resolved "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz" integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + picocolors@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pify@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== pify@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== pify@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" + resolved "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz" integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== pino-abstract-transport@v0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" + resolved "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz" integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== dependencies: duplexify "^4.1.2" @@ -4329,12 +4531,12 @@ pino-abstract-transport@v0.5.0: pino-std-serializers@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" + resolved "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz" integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== pino@7.11.0: version "7.11.0" - resolved "https://registry.yarnpkg.com/pino/-/pino-7.11.0.tgz#0f0ea5c4683dc91388081d44bff10c83125066f6" + resolved "https://registry.npmjs.org/pino/-/pino-7.11.0.tgz" integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== dependencies: atomic-sleep "^1.0.0" @@ -4351,17 +4553,17 @@ pino@7.11.0: pirates@^4.0.1: version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz" integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== pngjs@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" + resolved "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz" integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== postcss-import@^15.1.0: version "15.1.0" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz" integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== dependencies: postcss-value-parser "^4.0.0" @@ -4370,14 +4572,14 @@ postcss-import@^15.1.0: postcss-js@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz" integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== dependencies: camelcase-css "^2.0.1" postcss-load-config@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd" + resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz" integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== dependencies: lilconfig "^2.0.5" @@ -4385,14 +4587,14 @@ postcss-load-config@^4.0.1: postcss-nested@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" + resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz" integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== dependencies: postcss-selector-parser "^6.0.11" postcss-selector-parser@^6.0.11: version "6.0.13" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz" integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== dependencies: cssesc "^3.0.0" @@ -4400,69 +4602,69 @@ postcss-selector-parser@^6.0.11: postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@8.4.14: - version "8.4.14" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" - integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== +postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@>=8.0.9, postcss@8.4.24: + version "8.4.24" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz" + integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== dependencies: - nanoid "^3.3.4" + nanoid "^3.3.6" picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@8.4.24, postcss@^8.4.23: - version "8.4.24" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df" - integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== +postcss@8.4.14: + version "8.4.14" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz" + integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== dependencies: - nanoid "^3.3.6" + nanoid "^3.3.4" picocolors "^1.0.0" source-map-js "^1.0.2" preact@^10.12.0, preact@^10.5.9: version "10.15.1" - resolved "https://registry.yarnpkg.com/preact/-/preact-10.15.1.tgz#a1de60c9fc0c79a522d969c65dcaddc5d994eede" + resolved "https://registry.npmjs.org/preact/-/preact-10.15.1.tgz" integrity sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g== prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process-warning@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" + resolved "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz" integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== dependencies: loose-envify "^1.4.0" object-assign "^4.1.1" react-is "^16.13.1" -proxy-compare@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/proxy-compare/-/proxy-compare-2.5.1.tgz#17818e33d1653fbac8c2ec31406bce8a2966f600" - integrity sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA== +proxy-compare@2.5.0: + version "2.5.0" + resolved "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.5.0.tgz" + integrity sha512-f1us0OsVAJ3tdIMXGQx2lmseYS4YXe4W+sKF5g5ww/jV+5ogMadPt+sIZ+88Ga9kvMJsrRNWzCrKPpr6pMWYbA== punycode@^2.1.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== -qrcode@1.5.3, qrcode@^1.5.1: +qrcode@^1.5.1: version "1.5.3" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.3.tgz#03afa80912c0dccf12bc93f615a535aad1066170" + resolved "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz" integrity sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg== dependencies: dijkstrajs "^1.0.1" @@ -4470,53 +4672,73 @@ qrcode@1.5.3, qrcode@^1.5.1: pngjs "^5.0.0" yargs "^15.3.1" +qrcode@1.5.1: + version "1.5.1" + resolved "https://registry.npmjs.org/qrcode/-/qrcode-1.5.1.tgz" + integrity sha512-nS8NJ1Z3md8uTjKtP+SGGhfqmTCs5flU/xR623oI0JX+Wepz9R8UrRVCTBTJm3qGw3rH6jJ6MUHjkDx15cxSSg== + dependencies: + dijkstrajs "^1.0.1" + encode-utf8 "^1.0.3" + pngjs "^5.0.0" + yargs "^15.3.1" + qs@^6.10.3: version "6.11.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz" integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== dependencies: side-channel "^1.0.4" -query-string@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" - integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== +query-string@^6.13.5: + version "6.14.1" + resolved "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz" + integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== dependencies: - decode-uri-component "^0.2.2" + decode-uri-component "^0.2.0" filter-obj "^1.1.0" split-on-first "^1.0.0" strict-uri-encode "^2.0.0" -query-string@^6.13.5: - version "6.14.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" - integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== +query-string@7.1.1: + version "7.1.1" + resolved "https://registry.npmjs.org/query-string/-/query-string-7.1.1.tgz" + integrity sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w== dependencies: decode-uri-component "^0.2.0" filter-obj "^1.1.0" split-on-first "^1.0.0" strict-uri-encode "^2.0.0" +query-string@7.1.3: + version "7.1.3" + resolved "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz" + integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== + dependencies: + decode-uri-component "^0.2.2" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== quick-format-unescaped@^4.0.3: version "4.0.4" - resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + resolved "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz" integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" -react-dom@18.2.0: +"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", react-dom@^18.2.0: version "18.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== dependencies: loose-envify "^1.1.0" @@ -4524,26 +4746,44 @@ react-dom@18.2.0: react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react@18.2.0: +"react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.2.0, "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16.8, react@>=17.0.0: version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: loose-envify "^1.1.0" read-cache@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== dependencies: pify "^2.3.0" -readable-stream@^3.1.1, readable-stream@^3.5.0, readable-stream@^3.6.0: +readable-stream@^3.1.1: version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@^3.5.0: + version "3.6.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" @@ -4552,7 +4792,7 @@ readable-stream@^3.1.1, readable-stream@^3.5.0, readable-stream@^3.6.0: readable-stream@~2.3.6: version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" @@ -4565,24 +4805,24 @@ readable-stream@~2.3.6: readdirp@~3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" real-require@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" + resolved "https://registry.npmjs.org/real-require/-/real-require-0.1.0.tgz" integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== regenerator-runtime@^0.13.11: version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz" integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== dependencies: call-bind "^1.0.2" @@ -4591,27 +4831,27 @@ regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-main-filename@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-pkg-maps@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz" integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== resolve@^1.1.7, resolve@^1.22.1, resolve@^1.22.2: version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz" integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== dependencies: is-core-module "^2.11.0" @@ -4620,7 +4860,7 @@ resolve@^1.1.7, resolve@^1.22.1, resolve@^1.22.2: resolve@^2.0.0-next.4: version "2.0.0-next.4" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" + resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz" integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== dependencies: is-core-module "^2.9.0" @@ -4629,24 +4869,24 @@ resolve@^2.0.0-next.4: response-iterator@^0.2.6: version "0.2.6" - resolved "https://registry.yarnpkg.com/response-iterator/-/response-iterator-0.2.6.tgz#249005fb14d2e4eeb478a3f735a28fd8b4c9f3da" + resolved "https://registry.npmjs.org/response-iterator/-/response-iterator-0.2.6.tgz" integrity sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw== reusify@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" rpc-websockets@^7.5.1: version "7.5.1" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.1.tgz#e0a05d525a97e7efc31a0617f093a13a2e10c401" + resolved "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.1.tgz" integrity sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w== dependencies: "@babel/runtime" "^7.17.2" @@ -4659,43 +4899,38 @@ rpc-websockets@^7.5.1: run-applescript@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + resolved "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz" integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== dependencies: execa "^5.0.0" run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" rxjs@^6.6.3: version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-json-utils@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/safe-json-utils/-/safe-json-utils-1.1.1.tgz#0e883874467d95ab914c3f511096b89bfb3e63b1" + resolved "https://registry.npmjs.org/safe-json-utils/-/safe-json-utils-1.1.1.tgz" integrity sha512-SAJWGKDs50tAbiDXLf89PDwt9XYkWyANFWVzn4dTXl5QyI8t2o/bW5/OJl3lvc2WVU4MEpTo9Yz5NVFNsp+OJQ== safe-regex-test@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== dependencies: call-bind "^1.0.2" @@ -4704,51 +4939,58 @@ safe-regex-test@^1.0.0: safe-stable-stringify@^2.1.0: version "2.4.3" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz" integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== scheduler@^0.23.0: version "0.23.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== dependencies: loose-envify "^1.1.0" scrypt-js@3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + resolved "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== semver@^6.3.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.3.7, semver@^7.3.8: version "7.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz" integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== dependencies: lru-cache "^6.0.0" +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + set-blocking@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== setimmediate@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== sha.js@^2.4.11: version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" @@ -4756,19 +4998,19 @@ sha.js@^2.4.11: shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== side-channel@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: call-bind "^1.0.0" @@ -4777,12 +5019,12 @@ side-channel@^1.0.4: signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== siwe@^1.1.6: version "1.1.6" - resolved "https://registry.yarnpkg.com/siwe/-/siwe-1.1.6.tgz#b4b4fe7814654d5ea529171b2ede15f7ef7ef1ae" + resolved "https://registry.npmjs.org/siwe/-/siwe-1.1.6.tgz" integrity sha512-3WRdEil32Tc2vuNzqJ2/Z/MIvsvy0Nkzc2ov+QujmpHO7tM83dgcb47z0Pu236T4JQkOQCqQkq3AJ/rVIezniA== dependencies: "@spruceid/siwe-parser" "^1.1.3" @@ -4791,46 +5033,46 @@ siwe@^1.1.6: slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slash@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== sonic-boom@^2.2.1: version "2.8.0" - resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.8.0.tgz#c1def62a77425090e6ad7516aad8eb402e047611" + resolved "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz" integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== dependencies: atomic-sleep "^1.0.0" source-map-js@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== split-on-first@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz" integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== split2@^4.0.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== stop-iteration-iterator@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== dependencies: internal-slot "^1.0.4" stream-browserify@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz" integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== dependencies: inherits "~2.0.4" @@ -4838,22 +5080,29 @@ stream-browserify@^3.0.0: stream-shift@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== streamsearch@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== strict-uri-encode@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz" integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== +string_decoder@^1.1.1, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -4862,7 +5111,7 @@ string-width@^4.1.0, string-width@^4.2.0: string.prototype.matchall@^4.0.8: version "4.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz" integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== dependencies: call-bind "^1.0.2" @@ -4876,7 +5125,7 @@ string.prototype.matchall@^4.0.8: string.prototype.trim@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz" integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== dependencies: call-bind "^1.0.2" @@ -4885,7 +5134,7 @@ string.prototype.trim@^1.2.7: string.prototype.trimend@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz" integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== dependencies: call-bind "^1.0.2" @@ -4894,64 +5143,50 @@ string.prototype.trimend@^1.0.6: string.prototype.trimstart@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz" integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" es-abstract "^1.20.4" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-final-newline@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz" integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== styled-jsx@5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f" + resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz" integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== dependencies: client-only "0.0.1" sucrase@^3.32.0: version "3.32.0" - resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.32.0.tgz#c4a95e0f1e18b6847127258a75cf360bc568d4a7" + resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz" integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== dependencies: "@jridgewell/gen-mapping" "^0.3.2" @@ -4964,34 +5199,41 @@ sucrase@^3.32.0: superstruct@^0.14.2: version "0.14.2" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" + resolved "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz" integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== superstruct@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.3.tgz#de626a5b49c6641ff4d37da3c7598e7a87697046" + resolved "https://registry.npmjs.org/superstruct/-/superstruct-1.0.3.tgz" integrity sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg== supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== symbol-observable@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" + resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz" integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== synckit@^0.8.5: version "0.8.5" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" + resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz" integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== dependencies: "@pkgr/utils" "^2.3.1" @@ -4999,7 +5241,7 @@ synckit@^0.8.5: tailwindcss@3.3.2: version "3.3.2" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.2.tgz#2f9e35d715fdf0bbf674d90147a0684d7054a2d3" + resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz" integrity sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w== dependencies: "@alloc/quick-lru" "^5.2.0" @@ -5028,82 +5270,101 @@ tailwindcss@3.3.2: tapable@^2.2.0: version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== text-encoding-utf-8@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + resolved "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz" integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== thenify-all@^1.0.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz" integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== dependencies: thenify ">= 3.1.0 < 4" "thenify@>= 3.1.0 < 4": version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz" integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== dependencies: any-promise "^1.0.0" thread-stream@^0.15.1: version "0.15.2" - resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.15.2.tgz#fb95ad87d2f1e28f07116eb23d85aba3bc0425f4" + resolved "https://registry.npmjs.org/thread-stream/-/thread-stream-0.15.2.tgz" integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== dependencies: real-require "^0.1.0" "through@>=2.2.7 <3": version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== titleize@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + resolved "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz" integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" toggle-selection@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz" integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== tr46@~0.0.3: version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== ts-interface-checker@^0.1.9: version "0.1.13" - resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== ts-invariant@^0.10.3: version "0.10.3" - resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.10.3.tgz#3e048ff96e91459ffca01304dbc7f61c1f642f6c" + resolved "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz" integrity sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ== dependencies: tslib "^2.1.0" +ts-node@^10.9.1, ts-node@>=9.0.0: + version "10.9.1" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + tsconfig-paths@^3.14.1: version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz" integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== dependencies: "@types/json5" "^0.0.29" @@ -5111,53 +5372,68 @@ tsconfig-paths@^3.14.1: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@1.14.1, tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^1.9.0: version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.5.0: version "2.5.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== +tslib@1.14.1: + version "1.14.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" tweetnacl-util@^0.13.3: version "0.13.5" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.13.5.tgz#e39cd5d99709ee7125a18b03895b45a1299e475f" + resolved "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.13.5.tgz" integrity sha512-/4Q3hpPFAnbBjNLLOmdTdyvInBfZcQBTWy+LWbypmWxAKwOpSQOyyv4ZZts4CoiYtS8Skyix5CkOWytf7XNK9A== tweetnacl-util@^0.15.1: version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + resolved "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz" integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== tweetnacl@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" +type-detect@^4.0.0, type-detect@^4.0.5: + 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== + type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== typed-array-length@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== dependencies: call-bind "^1.0.2" @@ -5166,26 +5442,26 @@ typed-array-length@^1.0.4: typedarray-to-buffer@3.1.5: version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== dependencies: is-typedarray "^1.0.0" -typescript@5.1.3: +typescript@>=2.7, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta", typescript@>=3.3.1, typescript@>=4.9.4, typescript@5.1.3: version "5.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz" integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== uint8arrays@^3.0.0, uint8arrays@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" + resolved "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz" integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== dependencies: multiformats "^9.4.2" unbox-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== dependencies: call-bind "^1.0.2" @@ -5195,12 +5471,12 @@ unbox-primitive@^1.0.2: untildify@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== update-browserslist-db@^1.0.11: version "1.0.11" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz" integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== dependencies: escalade "^3.1.1" @@ -5208,31 +5484,31 @@ update-browserslist-db@^1.0.11: uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" -use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0: +use-sync-external-store@^1.2.0, use-sync-external-store@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== -utf-8-validate@^5.0.2: +utf-8-validate@^5.0.2, utf-8-validate@>=5.0.2: version "5.0.10" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + resolved "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz" integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== dependencies: node-gyp-build "^4.3.0" util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== util@^0.12.4: version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + resolved "https://registry.npmjs.org/util/-/util-0.12.5.tgz" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== dependencies: inherits "^2.0.3" @@ -5243,47 +5519,60 @@ util@^0.12.4: uuid@^8.3.2: version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== uuid@^9.0.0: version "9.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== -valtio@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.10.5.tgz#7852125e3b774b522827d96bd9c76d285c518678" - integrity sha512-jTp0k63VXf4r5hPoaC6a6LCG4POkVSh629WLi1+d5PlajLsbynTMd7qAgEiOSPxzoX5iNvbN7iZ/k/g29wrNiQ== +v8-compile-cache-lib@^3.0.1: + 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== + +valtio@1.10.3: + version "1.10.3" + resolved "https://registry.npmjs.org/valtio/-/valtio-1.10.3.tgz" + integrity sha512-t3Ez/+baJ+Z5tIyeaI6nCAbW/hrmcq2jditwg/X++o5IvCdiGirQKTOv1kJq0glgUo13v5oABCVGcinggBfiKw== dependencies: - proxy-compare "2.5.1" + proxy-compare "2.5.0" use-sync-external-store "1.2.0" -wagmi@^0.12.7: - version "0.12.13" - resolved "https://registry.yarnpkg.com/wagmi/-/wagmi-0.12.13.tgz#995cd453fcfa6a6b3aa3a8bf30f6b52c3fbd7879" - integrity sha512-1J+F68MztodPUo2OIFImiC3OoZD4gdryxTidfwQz9LJawXdBNmAOFvq0LQClrrqgFk0Gd3EoLo/MKGiEn2RsMg== +wagmi@^0.12.7, wagmi@0.12.7: + version "0.12.7" + resolved "https://registry.npmjs.org/wagmi/-/wagmi-0.12.7.tgz" + integrity sha512-L1yE+6KVeUNWKLMr2VXTB3bYHYJhC9kjt7HeAo1o4r4P6ZRJiTD7haTP+Lwzd4EqHCsyN4Zzfnb3Eh6RdcVwvA== dependencies: - "@tanstack/query-sync-storage-persister" "^4.27.1" - "@tanstack/react-query" "^4.28.0" - "@tanstack/react-query-persist-client" "^4.28.0" - "@wagmi/core" "0.10.11" + "@tanstack/query-sync-storage-persister" "^4.14.5" + "@tanstack/react-query" "^4.14.5" + "@tanstack/react-query-persist-client" "^4.14.5" + "@wagmi/core" "0.10.7" abitype "^0.3.0" use-sync-external-store "^1.2.0" +watchpack@2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + web-vitals@^3.0.4: version "3.3.2" - resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-3.3.2.tgz#83e8dbd0f8fba43c5fe2e601573e804afc771790" + resolved "https://registry.npmjs.org/web-vitals/-/web-vitals-3.3.2.tgz" integrity sha512-qRkpmSeKfEWAzNhtX541xA8gCJ+pqCqBmUlDVkVDSCSYUvfvNqF+k9g8I+uyreRcDBdfiJrd0/aLbTy5ydo49Q== webidl-conversions@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== whatwg-url@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" @@ -5291,7 +5580,7 @@ whatwg-url@^5.0.0: which-boxed-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: is-bigint "^1.0.1" @@ -5302,7 +5591,7 @@ which-boxed-primitive@^1.0.2: which-collection@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== dependencies: is-map "^2.0.1" @@ -5312,12 +5601,12 @@ which-collection@^1.0.1: which-module@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz" integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== which-typed-array@^1.1.2, which-typed-array@^1.1.9: version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz" integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== dependencies: available-typed-arrays "^1.0.5" @@ -5329,76 +5618,110 @@ which-typed-array@^1.1.2, which-typed-array@^1.1.9: which@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" word-wrap@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + wrap-ansi@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + 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" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@7.4.6: +ws@*, ws@^7.4.0, ws@^7.4.5, ws@7.4.6: version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== -ws@^7.4.0, ws@^7.4.5, ws@^7.5.1: +ws@^7.5.1: version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + resolved "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== ws@^8.5.0: version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + resolved "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== xtend@^4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz" integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + yallist@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@^2.1.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" + resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== yargs-parser@^18.1.2: version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz" integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^20.2.2, yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + yargs@^15.3.1: version "15.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + resolved "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz" integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== dependencies: cliui "^6.0.0" @@ -5413,31 +5736,49 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.2" +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + 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" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zen-observable-ts@^1.2.5: version "1.2.5" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz#6c6d9ea3d3a842812c6e9519209365a122ba8b58" + resolved "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz" integrity sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg== dependencies: zen-observable "0.8.15" zen-observable@0.8.15: version "0.8.15" - resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" + resolved "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== -zod@3.21.4, zod@^3.20.6: +zod@^3.20.6, zod@>=3.19.1, zod@3.21.4: version "3.21.4" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db" + resolved "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz" integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw== zustand@^4.3.1: version "4.3.8" - resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.3.8.tgz#37113df8e9e1421b0be1b2dca02b49b76210e7c4" + resolved "https://registry.npmjs.org/zustand/-/zustand-4.3.8.tgz" integrity sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg== dependencies: use-sync-external-store "1.2.0" diff --git a/lens-protocol/README.md b/lens-protocol/README.md new file mode 100644 index 0000000..b28f7b9 --- /dev/null +++ b/lens-protocol/README.md @@ -0,0 +1,20 @@ +Local copy of github/lens-protocol, contains all functionality of lens protocol and our smart contracts. + + +## Deploy Lens protocol on local fork + +- open 2 terminals +- in each, navigate to lens-protocol/core +- in the first, enter: + ```bash + npm install + npm run compile + npx hardhat node + ``` +- in the second, enter: + ```bash + npm run full-deploy-local + ``` + +That's similar to https://docs.lens.xyz/docs/deploying-the-protocol + diff --git a/lens-protocol/core/.dockerignore b/lens-protocol/core/.dockerignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/lens-protocol/core/.dockerignore @@ -0,0 +1 @@ +node_modules/ diff --git a/lens-protocol/core/.env.example b/lens-protocol/core/.env.example new file mode 100644 index 0000000..ef5655b --- /dev/null +++ b/lens-protocol/core/.env.example @@ -0,0 +1,11 @@ +MNEMONIC= +POLYGON_RPC_URL= +MUMBAI_RPC_URL= +KOVAN_RPC_URL= +ROPSTEN_RPC_URL= +MAINNET_RPC_URL= +BLOCK_EXPLORER_KEY= +TENDERLY_PROJECT= +TENDERLY_USERNAME= +TENDERLY_FORK_ID= +TENDERLY_HEAD_ID= diff --git a/lens-protocol/core/.eslintrc.json b/lens-protocol/core/.eslintrc.json new file mode 100644 index 0000000..995657a --- /dev/null +++ b/lens-protocol/core/.eslintrc.json @@ -0,0 +1,16 @@ +{ + "env": { "node": true }, + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "parserOptions": { + "ecmaVersion": 2020, + "sourceType": "module" + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier", + "plugin:prettier/recommended" + ], + "rules": {} +} diff --git a/lens-protocol/core/.gitignore b/lens-protocol/core/.gitignore new file mode 100644 index 0000000..1be6b0d --- /dev/null +++ b/lens-protocol/core/.gitignore @@ -0,0 +1,28 @@ +.env +#Hardhat files +cache +artifacts +node_modules +dist/ +build/ +.vscode +.idea +/.VSCodeCounter/ +/types +/typechain-types +/tasks/unpause.ts +/tasks/create-profile.ts +/tasks/post.ts +/tasks/follow.ts +/tasks/collect.ts +/tasks/test-module.ts + +/coverage +coverage.json +.coverage_artifacts +.coverage_cache +.coverage_contracts + +addresses.json + +contracts/core/modules/follow/SecretCodeFollowModule.sol \ No newline at end of file diff --git a/lens-protocol/core/.prettierignore b/lens-protocol/core/.prettierignore new file mode 100644 index 0000000..1467c2a --- /dev/null +++ b/lens-protocol/core/.prettierignore @@ -0,0 +1,5 @@ +artifacts +cache +node_modules +coverage +typechain-types \ No newline at end of file diff --git a/lens-protocol/core/.prettierrc b/lens-protocol/core/.prettierrc new file mode 100644 index 0000000..b4c479a --- /dev/null +++ b/lens-protocol/core/.prettierrc @@ -0,0 +1,17 @@ +{ + "printWidth": 100, + "trailingComma": "es5", + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "overrides": [ + { + "files": "*.sol", + "options": { + "semi": true, + "printWidth": 100, + "tabWidth": 4 + } + } + ] +} diff --git a/lens-protocol/core/.solcover.js b/lens-protocol/core/.solcover.js new file mode 100644 index 0000000..111825b --- /dev/null +++ b/lens-protocol/core/.solcover.js @@ -0,0 +1,10 @@ +module.exports = { + skipFiles: [ + '/core/base/ERC721Time.sol', + '/core/base/ERC721Enumerable.sol', + '/core/modules/follow/SecretCodeFollowModule.sol', + '/upgradeability', + '/interfaces', + '/mocks', + ], +}; diff --git a/lens-protocol/core/Dockerfile b/lens-protocol/core/Dockerfile new file mode 100644 index 0000000..da730a9 --- /dev/null +++ b/lens-protocol/core/Dockerfile @@ -0,0 +1,21 @@ +# syntax=docker/dockerfile:1.3 +FROM ethereum/solc:0.8.7 as build-deps + +FROM node:16 as build-packages + +COPY package*.json ./ +COPY tsconfig*.json ./ + +RUN npm ci --quiet + +FROM node:16 + +WORKDIR /src + +COPY --from=build-deps /usr/bin/solc /usr/bin/solc +COPY --from=build-packages /node_modules /node_modules +COPY docker-entrypoint.sh /docker-entrypoint.sh + +USER node + +ENTRYPOINT ["sh", "/docker-entrypoint.sh"] \ No newline at end of file diff --git a/lens-protocol/core/LICENSE b/lens-protocol/core/LICENSE new file mode 100644 index 0000000..57224b1 --- /dev/null +++ b/lens-protocol/core/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Avara Labs 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/lens-protocol/core/README.md b/lens-protocol/core/README.md new file mode 100644 index 0000000..0d68820 --- /dev/null +++ b/lens-protocol/core/README.md @@ -0,0 +1,201 @@ +``` + &&&&& &&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&& &&&&& /&&&&&&&&&&&&&&&&& + &&&&& &&&&&&&&&&&&&&&&&&&&&&&& &&&& &&&&& &&&&& &&&&&&( .&&&&&&* + &&&&& &&&&& &&&& &&&&& &&&&& &&&&/ &&&&& + &&&&& &&&&& &&&& &&&&& &&&&& &&&&& &&&&, + &&&&& &&&&& &&&& &&&&& &&&&& &&&&& &&&&& + &&&&& &&&&& &&&& &&&&& &&&&& &&&&&& + &&&&& &&&&& &&&& &&&&% &&&&& &&&&&&&&&&& + &&&&& &&&&&&&&&&&&&&&&&&&& &&&& &&&&/ &&&&& &&&&&&&&&&&&&& + &&&&& &&&&& &&&& &&&&* &&&&& ,&&&&&&&& + &&&&& &&&&& &&&& &&&& &&&&& (&&&&& + &&&&& &&&&& &&&& &&&& &&&&& &&&&& &&&& + &&&&& &&&&& &&&& &&&& &&&&& &&&& &&&& + &&&&& &&&&& &&&& *&&&& &&&&& /&&&&& &&&&& + &&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& &&&& (&&&& &&&&& &&&&&&& &&&&&&& + &&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& &&&& %&&&&&&&&&& &&&&&&&&&&&&&&&&&, + + + + + _( )_ _ wWWWw _ _( )_ _ wWWWw _ + @@@@ (_ _) ( ) _ @@@@ (___) _( )_ @@@@ (_ _) ( ) _ @@@@ (___) _( )_ + @@()@@ wWWWw (_)\ ( ) _( )_ @@()@@ Y (_ _) @@()@@ wWWWw (_)\ ( ) _( )_ @@()@@ Y (_ _) + @@@@ (___) |/ ( ) (_____) @@@@ \|/ (_)\ @@@@ (___) |/ ( ) (_____) @@@@ \|/ (_)\ + / Y \| (_) | \| |/ | / Y \| (_) | \| |/ | + \ | \|/ | / \ | / \|/ |/ \ \|/ \ | \|/ | / \ | / \|/ |/ \ \|/ + | | | | | | | | | | | | | | | | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + _//|\_ | |\ _//|\_ /|\ |\_ |\___ |\ _//|\_ | |\ _//|\_ /|\ |\_ |\___ |\ + | \_/ / \__ / \_ | \ _/ | _| | \_/ / \__ / \_ | \ _/ | _| + /|\_ _/ _/\ \__ /\_ / \_ |_ /|\_ _/ _/\ \__ /\_ / \_ |_ + / | | \___ \_ /\ \ / / | | \___ \_ /\ \ / + +``` + +# Lens Protocol + + The Lens Protocol is a decentralized, non-custodial social graph. Lens implements unique, on-chain social interaction mechanisms analogous to commonly understood Web2 social media interactions, but significantly expanded with unique functionality that empower communities to form and participants to own their own social graph. + +## Setup + +> For now only Linux and macOS are known to work +> +> We are now figuring out what works for Windows, instructions will be updated soon +> +> (feel free to experiment and submit PR's) + +The environment is built using Docker Compose, note that your `.env` file must have the RPC URL of the network you want to use, and an optional `MNEMONIC` and `BLOCK_EXPLORER_KEY`, defined like so, assuming you choose to use Mumbai network: + +``` +MNEMONIC="MNEMONIC YOU WANT TO DERIVE WALLETS FROM HERE" +MUMBAI_RPC_URL="YOUR RPC URL HERE" +BLOCK_EXPLORER_KEY="YOUR BLOCK EXPLORER API KEY HERE" +``` + +With the environment file set up, you can move on to using Docker: + +```bash +export USERID=$UID && docker-compose build && docker-compose run --name lens contracts-env bash +``` + +If you need additional terminals: + +```bash +docker exec -it lens bash +``` + +From there, have fun! + +Here are a few self-explanatory scripts: + +```bash +npm run test +npm run coverage +npm run compile +``` + +Cleanup leftover Docker containers: + +```bash +USERID=$UID docker-compose down +``` + +## Protocol Overview + +The Lens Protocol transfers ownership of social graphs to the participants of that graph themselves. This is achieved by creating direct links between `profiles` and their `followers`, while allowing fine-grained control of additional logic, including monetization, to be executed during those interactions on a profile-by-profile basis. + +Here's how it works... + +### Profiles + +Any address can create a profile and receive an ERC-721 `Lens Profile` NFT. Profiles are represented by a `ProfileStruct`: + +``` +/** + * @notice A struct containing profile data. + * + * @param pubCount The number of publications made to this profile. + * @param followNFT The address of the followNFT associated with this profile, can be empty.. + * @param followModule The address of the current follow module in use by this profile, can be empty. + * @param handle The profile's associated handle. + * @param uri The URI to be displayed for the profile NFT. + */ +struct ProfileStruct { + uint256 pubCount; + address followNFT; + address followModule; + string handle; + string uri; +} +``` + +Profiles have a specific URI associated with them, which is meant to include metadata, such as a link to a profile picture or a display name for instance, the JSON standard for this URI is not yet determined. Profile owners can always change their follow module or profile URI. + +#### Publications + +Profile owners can `publish` to any profile they own. There are three `publication` types: `Post`, `Comment` and `Mirror`. Profile owners can also set and initialize the `Follow Module` associated with their profile. + +Publications are on-chain content created and published via profiles. Profile owners can create (publish) three publication types, outlined below. They are represented by a `PublicationStruct`: + +``` +/** + * @notice A struct containing data associated with each new publication. + * + * @param profileIdPointed The profile token ID this publication points to, for mirrors and comments. + * @param pubIdPointed The publication ID this publication points to, for mirrors and comments. + * @param contentURI The URI associated with this publication. + * @param referenceModule The address of the current reference module in use by this profile, can be empty. + * @param collectModule The address of the collect module associated with this publication, this exists for all publication. + * @param collectNFT The address of the collectNFT associated with this publication, if any. + */ +struct PublicationStruct { + uint256 profileIdPointed; + uint256 pubIdPointed; + string contentURI; + address referenceModule; + address collectModule; + address collectNFT; +} +``` + +#### Publication Types + +##### Post + +This is the standard publication type, akin to a regular post on traditional social media platforms. Posts contain: + +1. A URI, pointing to the actual publication body's [metadata](https://docs.lens.xyz/docs/metadata-standards) JSON, including any images or text. +2. An uninitialized pointer, since pointers are only needed in mirrors and comments. + +##### Comment + +This is a publication type that points back to another publication, whether it be a post, comment or mirror, akin to a regular comment on traditional social media. Comments contain: + +1. A URI, just like posts, pointing to the publication body's [metadata](https://docs.lens.xyz/docs/metadata-standards) JSON. +2. An initialized pointer, containing the profile ID and the publication ID of the publication commented on. + +##### Mirror + +This is a publication type that points to another publication, note that mirrors cannot, themselves, be mirrored (doing so instead mirrors the pointed content). Mirrors have no original content of its own. Akin to a "share" on traditional social media. Mirrors contain: + +1. An empty URI, since they cannot have content associated with them. +2. An initialized pointer, containing the profile ID and the publication ID of the mirrored publication. + +### Profile Interaction + +There are two types of profile interactions: follows and collects. + +#### Follows + +Wallets can follow profiles, executing modular follow processing logic (in that profile's selected follow module) and receiving a `Follow NFT`. Each profile has a connected, unique `FollowNFT` contract, which is first deployed upon successful follow. Follow NFTs are NFTs with integrated voting and delegation capability. + +The inclusion of voting and delegation right off the bat means that follow NFTs have the built-in capability to create a spontaneous DAO around any profile. Furthermore, holding follow NFTs allows followers to `collect` publications from the profile they are following (except mirrors, which are equivalent to shares in Web2 social media, and require following the original publishing profile to collect). + +#### Collects + +Collecting works in a modular fashion as well, every publication (except mirrors) requires a `Collect Module` to be selected and initialized. This module, similarly to follow modules, can contain any arbitrary logic to be executed upon collects. Successful collects result in a new, unique NFT being minted, essentially as a saved copy of the original publication. There is one deployed collect NFT contract per publication, and it's deployed upon the first successful collect. + +When a mirror is collected, what happens behind the scenes is the original, mirrored publication is collected, and the mirror publisher's profile ID is passed as a "referrer." This allows neat functionality where collect modules that incur a fee can, for instance, reward referrals. Note that the `Collected` event, which is emitted upon collection, indexes the profile and publication directly being passed, which, in case of a mirror, is different than the actual original publication getting collected (which is emitted unindexed). + +Alright, that was a mouthful! Let's move on to more specific details about Lens's core principle: Modularity. + +## Lens Modularity + +Stepping back for a moment, the core concept behind modules is to allow as much freedom as possible to the community to come up with new, innovative interaction mechanisms between social graph participants. For security purposes, this is achieved by including a whitelisted list of modules controlled by governance. + +To recap, the Lens Protocol has three types of modules: + +1. `Follow Modules` contain custom logic to be executed upon follow. +2. `Collect Modules` contain custom logic to be executed upon collect. Typically, these modules include at least a check that the collector is a follower. +3. `Reference Modules` contain custom logic to be executed upon comment and mirror. These modules can be used to limit who is able to comment and interact with a profile. + +Note that collect and reference modules should _not_ assume that a publication cannot be re-initialized, and thus should include front-running protection as a security measure if needed, as if the publication data was not static. This is even more prominent in follow modules, where it can absolutely be changed for a given profile. + +Lastly, there is also a `ModuleGlobals` contract which acts as a central data provider for modules. It is controlled by a specific governance address which can be set to a different executor compared to the Hub's governance. It's expected that modules will fetch dynamically changing data, such as the module globals governance address, the treasury address, the treasury fee as well as a list of whitelisted currencies. + +### Upgradeability + +This iteration of the Lens Protocol implements a transparent upgradeable proxy for the central hub to be controlled by governance. There are no other aspects of the protocol that are upgradeable. In an ideal world, the hub will not require upgrades due to the system's inherent modularity and openness, upgradeability is there only to implement new, breaking changes that would be impossible, or unreasonable to implement otherwise. + +This does come with a few caveats, for instance, the `ModuleGlobals` contract implements a currency whitelist, but it is not upgradeable, so the "removal" of a currency whitelist in a module would require a specific new module that does not query the `ModuleGlobals` contract for whitelisted currencies. diff --git a/lens-protocol/core/audit/PeckShield-Audit-Report-LensProtocol-v1.0.pdf b/lens-protocol/core/audit/PeckShield-Audit-Report-LensProtocol-v1.0.pdf new file mode 100644 index 0000000..7259754 Binary files /dev/null and b/lens-protocol/core/audit/PeckShield-Audit-Report-LensProtocol-v1.0.pdf differ diff --git a/lens-protocol/core/contracts/core/CollectNFT.sol b/lens-protocol/core/contracts/core/CollectNFT.sol new file mode 100644 index 0000000..2b46131 --- /dev/null +++ b/lens-protocol/core/contracts/core/CollectNFT.sol @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ICollectNFT} from '../interfaces/ICollectNFT.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {Errors} from '../libraries/Errors.sol'; +import {Events} from '../libraries/Events.sol'; +import {LensNFTBase} from './base/LensNFTBase.sol'; +import {ERC721Enumerable} from './base/ERC721Enumerable.sol'; + +/** + * @title CollectNFT + * @author Lens Protocol + * + * @notice This is the NFT contract that is minted upon collecting a given publication. It is cloned upon + * the first collect for a given publication, and the token URI points to the original publication's contentURI. + */ +contract CollectNFT is LensNFTBase, ICollectNFT { + address public immutable HUB; + + uint256 internal _profileId; + uint256 internal _pubId; + uint256 internal _tokenIdCounter; + + bool private _initialized; + + uint256 internal _royaltyBasisPoints; + + // bytes4(keccak256('royaltyInfo(uint256,uint256)')) == 0x2a55205a + bytes4 internal constant INTERFACE_ID_ERC2981 = 0x2a55205a; + uint16 internal constant BASIS_POINTS = 10000; + + // We create the CollectNFT with the pre-computed HUB address before deploying the hub proxy in order + // to initialize the hub proxy at construction. + constructor(address hub) { + if (hub == address(0)) revert Errors.InitParamsInvalid(); + HUB = hub; + _initialized = true; + } + + /// @inheritdoc ICollectNFT + function initialize( + uint256 profileId, + uint256 pubId, + string calldata name, + string calldata symbol + ) external override { + if (_initialized) revert Errors.Initialized(); + _initialized = true; + _royaltyBasisPoints = 1000; // 10% of royalties + _profileId = profileId; + _pubId = pubId; + super._initialize(name, symbol); + emit Events.CollectNFTInitialized(profileId, pubId, block.timestamp); + } + + /// @inheritdoc ICollectNFT + function mint(address to) external override returns (uint256) { + if (msg.sender != HUB) revert Errors.NotHub(); + unchecked { + uint256 tokenId = ++_tokenIdCounter; + _mint(to, tokenId); + return tokenId; + } + } + + /// @inheritdoc ICollectNFT + function getSourcePublicationPointer() external view override returns (uint256, uint256) { + return (_profileId, _pubId); + } + + function tokenURI(uint256 tokenId) public view override returns (string memory) { + if (!_exists(tokenId)) revert Errors.TokenDoesNotExist(); + return ILensHub(HUB).getContentURI(_profileId, _pubId); + } + + /** + * @notice Changes the royalty percentage for secondary sales. Can only be called publication's + * profile owner. + * + * @param royaltyBasisPoints The royalty percentage meassured in basis points. Each basis point + * represents 0.01%. + */ + function setRoyalty(uint256 royaltyBasisPoints) external { + if (IERC721(HUB).ownerOf(_profileId) == msg.sender) { + if (royaltyBasisPoints > BASIS_POINTS) { + revert Errors.InvalidParameter(); + } else { + _royaltyBasisPoints = royaltyBasisPoints; + } + } else { + revert Errors.NotProfileOwner(); + } + } + + /** + * @notice Called with the sale price to determine how much royalty + * is owed and to whom. + * + * @param tokenId The token ID of the NFT queried for royalty information. + * @param salePrice The sale price of the NFT specified. + * @return A tuple with the address who should receive the royalties and the royalty + * payment amount for the given sale price. + */ + function royaltyInfo(uint256 tokenId, uint256 salePrice) + external + view + returns (address, uint256) + { + return (IERC721(HUB).ownerOf(_profileId), (salePrice * _royaltyBasisPoints) / BASIS_POINTS); + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC721Enumerable) + returns (bool) + { + return interfaceId == INTERFACE_ID_ERC2981 || super.supportsInterface(interfaceId); + } + + /** + * @dev Upon transfers, we emit the transfer event in the hub. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 tokenId + ) internal override { + super._beforeTokenTransfer(from, to, tokenId); + ILensHub(HUB).emitCollectNFTTransferEvent(_profileId, _pubId, tokenId, from, to); + } +} diff --git a/lens-protocol/core/contracts/core/FollowNFT.sol b/lens-protocol/core/contracts/core/FollowNFT.sol new file mode 100644 index 0000000..e9d1d1a --- /dev/null +++ b/lens-protocol/core/contracts/core/FollowNFT.sol @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IFollowNFT} from '../interfaces/IFollowNFT.sol'; +import {IFollowModule} from '../interfaces/IFollowModule.sol'; +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {Errors} from '../libraries/Errors.sol'; +import {Events} from '../libraries/Events.sol'; +import {DataTypes} from '../libraries/DataTypes.sol'; +import {Constants} from '../libraries/Constants.sol'; +import {LensNFTBase} from './base/LensNFTBase.sol'; + +/** + * @title FollowNFT + * @author Lens Protocol + * + * @notice This contract is the NFT that is minted upon following a given profile. It is cloned upon first follow for a + * given profile, and includes built-in governance power and delegation mechanisms. + * + * NOTE: This contract assumes total NFT supply for this follow NFT will never exceed 2^128 - 1 + */ +contract FollowNFT is LensNFTBase, IFollowNFT { + struct Snapshot { + uint128 blockNumber; + uint128 value; + } + + address public immutable HUB; + + bytes32 internal constant DELEGATE_BY_SIG_TYPEHASH = + keccak256( + 'DelegateBySig(address delegator,address delegatee,uint256 nonce,uint256 deadline)' + ); + + mapping(address => mapping(uint256 => Snapshot)) internal _snapshots; + mapping(address => address) internal _delegates; + mapping(address => uint256) internal _snapshotCount; + mapping(uint256 => Snapshot) internal _delSupplySnapshots; + uint256 internal _delSupplySnapshotCount; + uint256 internal _profileId; + uint256 internal _tokenIdCounter; + + bool private _initialized; + + // We create the FollowNFT with the pre-computed HUB address before deploying the hub. + constructor(address hub) { + if (hub == address(0)) revert Errors.InitParamsInvalid(); + HUB = hub; + _initialized = true; + } + + /// @inheritdoc IFollowNFT + function initialize(uint256 profileId) external override { + if (_initialized) revert Errors.Initialized(); + _initialized = true; + _profileId = profileId; + emit Events.FollowNFTInitialized(profileId, block.timestamp); + } + + /// @inheritdoc IFollowNFT + function mint(address to) external override returns (uint256) { + if (msg.sender != HUB) revert Errors.NotHub(); + unchecked { + uint256 tokenId = ++_tokenIdCounter; + _mint(to, tokenId); + return tokenId; + } + } + + /// @inheritdoc IFollowNFT + function delegate(address delegatee) external override { + _delegate(msg.sender, delegatee); + } + + /// @inheritdoc IFollowNFT + function delegateBySig( + address delegator, + address delegatee, + DataTypes.EIP712Signature calldata sig + ) external override { + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + DELEGATE_BY_SIG_TYPEHASH, + delegator, + delegatee, + sigNonces[delegator]++, + sig.deadline + ) + ) + ), + delegator, + sig + ); + } + _delegate(delegator, delegatee); + } + + /// @inheritdoc IFollowNFT + function getPowerByBlockNumber(address user, uint256 blockNumber) + external + view + override + returns (uint256) + { + if (blockNumber > block.number) revert Errors.BlockNumberInvalid(); + uint256 snapshotCount = _snapshotCount[user]; + if (snapshotCount == 0) return 0; // Returning zero since this means the user never delegated and has no power + return _getSnapshotValueByBlockNumber(_snapshots[user], blockNumber, snapshotCount); + } + + /// @inheritdoc IFollowNFT + function getDelegatedSupplyByBlockNumber(uint256 blockNumber) + external + view + override + returns (uint256) + { + if (blockNumber > block.number) revert Errors.BlockNumberInvalid(); + uint256 snapshotCount = _delSupplySnapshotCount; + if (snapshotCount == 0) return 0; // Returning zero since this means a delegation has never occurred + return _getSnapshotValueByBlockNumber(_delSupplySnapshots, blockNumber, snapshotCount); + } + + function name() public view override returns (string memory) { + string memory handle = ILensHub(HUB).getHandle(_profileId); + return string(abi.encodePacked(handle, Constants.FOLLOW_NFT_NAME_SUFFIX)); + } + + function symbol() public view override returns (string memory) { + string memory handle = ILensHub(HUB).getHandle(_profileId); + bytes4 firstBytes = bytes4(bytes(handle)); + return string(abi.encodePacked(firstBytes, Constants.FOLLOW_NFT_SYMBOL_SUFFIX)); + } + + function _getSnapshotValueByBlockNumber( + mapping(uint256 => Snapshot) storage _shots, + uint256 blockNumber, + uint256 snapshotCount + ) internal view returns (uint256) { + unchecked { + uint256 lower = 0; + uint256 upper = snapshotCount - 1; + + // First check most recent snapshot + if (_shots[upper].blockNumber <= blockNumber) return _shots[upper].value; + + // Next check implicit zero balance + if (_shots[lower].blockNumber > blockNumber) return 0; + + while (upper > lower) { + uint256 center = upper - (upper - lower) / 2; + Snapshot memory snapshot = _shots[center]; + if (snapshot.blockNumber == blockNumber) { + return snapshot.value; + } else if (snapshot.blockNumber < blockNumber) { + lower = center; + } else { + upper = center - 1; + } + } + return _shots[lower].value; + } + } + + /** + * @dev This returns the follow NFT URI fetched from the hub. + */ + function tokenURI(uint256 tokenId) public view override returns (string memory) { + if (!_exists(tokenId)) revert Errors.TokenDoesNotExist(); + return ILensHub(HUB).getFollowNFTURI(_profileId); + } + + /** + * @dev Upon transfers, we move the appropriate delegations, and emit the transfer event in the hub. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 tokenId + ) internal override { + address fromDelegatee = _delegates[from]; + address toDelegatee = _delegates[to]; + address followModule = ILensHub(HUB).getFollowModule(_profileId); + + _moveDelegate(fromDelegatee, toDelegatee, 1); + + super._beforeTokenTransfer(from, to, tokenId); + ILensHub(HUB).emitFollowNFTTransferEvent(_profileId, tokenId, from, to); + if (followModule != address(0)) { + IFollowModule(followModule).followModuleTransferHook(_profileId, from, to, tokenId); + } + } + + function _delegate(address delegator, address delegatee) internal { + uint256 delegatorBalance = balanceOf(delegator); + address previousDelegate = _delegates[delegator]; + _delegates[delegator] = delegatee; + _moveDelegate(previousDelegate, delegatee, delegatorBalance); + } + + function _moveDelegate( + address from, + address to, + uint256 amount + ) internal { + unchecked { + bool fromZero = from == address(0); + if (!fromZero) { + uint256 fromSnapshotCount = _snapshotCount[from]; + + // Underflow is impossible since, if from != address(0), then a delegation must have occurred (at least 1 snapshot) + uint256 previous = _snapshots[from][fromSnapshotCount - 1].value; + uint128 newValue = uint128(previous - amount); + + _writeSnapshot(from, newValue, fromSnapshotCount); + emit Events.FollowNFTDelegatedPowerChanged(from, newValue, block.timestamp); + } + + if (to != address(0)) { + // if from == address(0) then this is an initial delegation (add amount to supply) + if (fromZero) { + // It is expected behavior that the `previousDelSupply` underflows upon the first delegation, + // returning the expected value of zero + uint256 delSupplySnapshotCount = _delSupplySnapshotCount; + uint128 previousDelSupply = _delSupplySnapshots[delSupplySnapshotCount - 1] + .value; + uint128 newDelSupply = uint128(previousDelSupply + amount); + _writeSupplySnapshot(newDelSupply, delSupplySnapshotCount); + } + + // It is expected behavior that `previous` underflows upon the first delegation to an address, + // returning the expected value of zero + uint256 toSnapshotCount = _snapshotCount[to]; + uint128 previous = _snapshots[to][toSnapshotCount - 1].value; + uint128 newValue = uint128(previous + amount); + _writeSnapshot(to, newValue, toSnapshotCount); + emit Events.FollowNFTDelegatedPowerChanged(to, newValue, block.timestamp); + } else { + // If from != address(0) then this is removing a delegation, otherwise we're dealing with a + // non-delegated burn of tokens and don't need to take any action + if (!fromZero) { + // Upon removing delegation (from != address(0) && to == address(0)), supply calculations cannot + // underflow because if from != address(0), then a delegation must have previously occurred, so + // the snapshot count must be >= 1 and the previous delegated supply must be >= amount + uint256 delSupplySnapshotCount = _delSupplySnapshotCount; + uint128 previousDelSupply = _delSupplySnapshots[delSupplySnapshotCount - 1] + .value; + uint128 newDelSupply = uint128(previousDelSupply - amount); + _writeSupplySnapshot(newDelSupply, delSupplySnapshotCount); + } + } + } + } + + function _writeSnapshot( + address owner, + uint128 newValue, + uint256 ownerSnapshotCount + ) internal { + unchecked { + uint128 currentBlock = uint128(block.number); + mapping(uint256 => Snapshot) storage ownerSnapshots = _snapshots[owner]; + + // Doing multiple operations in the same block + if ( + ownerSnapshotCount != 0 && + ownerSnapshots[ownerSnapshotCount - 1].blockNumber == currentBlock + ) { + ownerSnapshots[ownerSnapshotCount - 1].value = newValue; + } else { + ownerSnapshots[ownerSnapshotCount] = Snapshot(currentBlock, newValue); + _snapshotCount[owner] = ownerSnapshotCount + 1; + } + } + } + + function _writeSupplySnapshot(uint128 newValue, uint256 supplySnapshotCount) internal { + unchecked { + uint128 currentBlock = uint128(block.number); + + // Doing multiple operations in the same block + if ( + supplySnapshotCount != 0 && + _delSupplySnapshots[supplySnapshotCount - 1].blockNumber == currentBlock + ) { + _delSupplySnapshots[supplySnapshotCount - 1].value = newValue; + } else { + _delSupplySnapshots[supplySnapshotCount] = Snapshot(currentBlock, newValue); + _delSupplySnapshotCount = supplySnapshotCount + 1; + } + } + } +} diff --git a/lens-protocol/core/contracts/core/LensHub.sol b/lens-protocol/core/contracts/core/LensHub.sol new file mode 100644 index 0000000..9b57ea4 --- /dev/null +++ b/lens-protocol/core/contracts/core/LensHub.sol @@ -0,0 +1,1040 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {Events} from '../libraries/Events.sol'; +import {Helpers} from '../libraries/Helpers.sol'; +import {Constants} from '../libraries/Constants.sol'; +import {DataTypes} from '../libraries/DataTypes.sol'; +import {Errors} from '../libraries/Errors.sol'; +import {PublishingLogic} from '../libraries/PublishingLogic.sol'; +import {ProfileTokenURILogic} from '../libraries/ProfileTokenURILogic.sol'; +import {InteractionLogic} from '../libraries/InteractionLogic.sol'; +import {LensNFTBase} from './base/LensNFTBase.sol'; +import {LensMultiState} from './base/LensMultiState.sol'; +import {LensHubStorage} from './storage/LensHubStorage.sol'; +import {VersionedInitializable} from '../upgradeability/VersionedInitializable.sol'; +import {IERC721Enumerable} from '@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol'; + +/** + * @title LensHub + * @author Lens Protocol + * + * @notice This is the main entrypoint of the Lens Protocol. It contains governance functionality as well as + * publishing and profile interaction functionality. + * + * NOTE: The Lens Protocol is unique in that frontend operators need to track a potentially overwhelming + * number of NFT contracts and interactions at once. For that reason, we've made two quirky design decisions: + * 1. Both Follow & Collect NFTs invoke an LensHub callback on transfer with the sole purpose of emitting an event. + * 2. Almost every event in the protocol emits the current block timestamp, reducing the need to fetch it manually. + */ +contract LensHub is LensNFTBase, VersionedInitializable, LensMultiState, LensHubStorage, ILensHub { + uint256 internal constant REVISION = 1; + + address internal immutable FOLLOW_NFT_IMPL; + address internal immutable COLLECT_NFT_IMPL; + + /** + * @dev This modifier reverts if the caller is not the configured governance address. + */ + modifier onlyGov() { + _validateCallerIsGovernance(); + _; + } + + /** + * @dev The constructor sets the immutable follow & collect NFT implementations. + * + * @param followNFTImpl The follow NFT implementation address. + * @param collectNFTImpl The collect NFT implementation address. + */ + constructor(address followNFTImpl, address collectNFTImpl) { + if (followNFTImpl == address(0)) revert Errors.InitParamsInvalid(); + if (collectNFTImpl == address(0)) revert Errors.InitParamsInvalid(); + FOLLOW_NFT_IMPL = followNFTImpl; + COLLECT_NFT_IMPL = collectNFTImpl; + } + + /// @inheritdoc ILensHub + function initialize( + string calldata name, + string calldata symbol, + address newGovernance + ) external override initializer { + super._initialize(name, symbol); + _setState(DataTypes.ProtocolState.Paused); + _setGovernance(newGovernance); + } + + /// *********************** + /// *****GOV FUNCTIONS***** + /// *********************** + + /// @inheritdoc ILensHub + function setGovernance(address newGovernance) external override onlyGov { + _setGovernance(newGovernance); + } + + /// @inheritdoc ILensHub + function setEmergencyAdmin(address newEmergencyAdmin) external override onlyGov { + address prevEmergencyAdmin = _emergencyAdmin; + _emergencyAdmin = newEmergencyAdmin; + emit Events.EmergencyAdminSet( + msg.sender, + prevEmergencyAdmin, + newEmergencyAdmin, + block.timestamp + ); + } + + /// @inheritdoc ILensHub + function setState(DataTypes.ProtocolState newState) external override { + if (msg.sender == _emergencyAdmin) { + if (newState == DataTypes.ProtocolState.Unpaused) + revert Errors.EmergencyAdminCannotUnpause(); + _validateNotPaused(); + } else if (msg.sender != _governance) { + revert Errors.NotGovernanceOrEmergencyAdmin(); + } + _setState(newState); + } + + ///@inheritdoc ILensHub + function whitelistProfileCreator(address profileCreator, bool whitelist) + external + override + onlyGov + { + _profileCreatorWhitelisted[profileCreator] = whitelist; + emit Events.ProfileCreatorWhitelisted(profileCreator, whitelist, block.timestamp); + } + + /// @inheritdoc ILensHub + function whitelistFollowModule(address followModule, bool whitelist) external override onlyGov { + _followModuleWhitelisted[followModule] = whitelist; + emit Events.FollowModuleWhitelisted(followModule, whitelist, block.timestamp); + } + + /// @inheritdoc ILensHub + function whitelistReferenceModule(address referenceModule, bool whitelist) + external + override + onlyGov + { + _referenceModuleWhitelisted[referenceModule] = whitelist; + emit Events.ReferenceModuleWhitelisted(referenceModule, whitelist, block.timestamp); + } + + /// @inheritdoc ILensHub + function whitelistCollectModule(address collectModule, bool whitelist) + external + override + onlyGov + { + _collectModuleWhitelisted[collectModule] = whitelist; + emit Events.CollectModuleWhitelisted(collectModule, whitelist, block.timestamp); + } + + /// ********************************* + /// *****PROFILE OWNER FUNCTIONS***** + /// ********************************* + + /// @inheritdoc ILensHub + function createProfile(DataTypes.CreateProfileData calldata vars) + external + override + whenNotPaused + returns (uint256) + { + if (!_profileCreatorWhitelisted[msg.sender]) revert Errors.ProfileCreatorNotWhitelisted(); + unchecked { + uint256 profileId = ++_profileCounter; + _mint(vars.to, profileId); + PublishingLogic.createProfile( + vars, + profileId, + _profileIdByHandleHash, + _profileById, + _followModuleWhitelisted + ); + return profileId; + } + } + + /// @inheritdoc ILensHub + function setDefaultProfile(uint256 profileId) external override whenNotPaused { + _setDefaultProfile(msg.sender, profileId); + } + + /// @inheritdoc ILensHub + function setDefaultProfileWithSig(DataTypes.SetDefaultProfileWithSigData calldata vars) + external + override + whenNotPaused + { + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + SET_DEFAULT_PROFILE_WITH_SIG_TYPEHASH, + vars.wallet, + vars.profileId, + sigNonces[vars.wallet]++, + vars.sig.deadline + ) + ) + ), + vars.wallet, + vars.sig + ); + _setDefaultProfile(vars.wallet, vars.profileId); + } + } + + /// @inheritdoc ILensHub + function setFollowModule( + uint256 profileId, + address followModule, + bytes calldata followModuleInitData + ) external override whenNotPaused { + _validateCallerIsProfileOwner(profileId); + PublishingLogic.setFollowModule( + profileId, + followModule, + followModuleInitData, + _profileById[profileId], + _followModuleWhitelisted + ); + } + + /// @inheritdoc ILensHub + function setFollowModuleWithSig(DataTypes.SetFollowModuleWithSigData calldata vars) + external + override + whenNotPaused + { + address owner = ownerOf(vars.profileId); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + SET_FOLLOW_MODULE_WITH_SIG_TYPEHASH, + vars.profileId, + vars.followModule, + keccak256(vars.followModuleInitData), + sigNonces[owner]++, + vars.sig.deadline + ) + ) + ), + owner, + vars.sig + ); + } + PublishingLogic.setFollowModule( + vars.profileId, + vars.followModule, + vars.followModuleInitData, + _profileById[vars.profileId], + _followModuleWhitelisted + ); + } + + /// @inheritdoc ILensHub + function setDispatcher(uint256 profileId, address dispatcher) external override whenNotPaused { + _validateCallerIsProfileOwner(profileId); + _setDispatcher(profileId, dispatcher); + } + + /// @inheritdoc ILensHub + function setDispatcherWithSig(DataTypes.SetDispatcherWithSigData calldata vars) + external + override + whenNotPaused + { + address owner = ownerOf(vars.profileId); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + SET_DISPATCHER_WITH_SIG_TYPEHASH, + vars.profileId, + vars.dispatcher, + sigNonces[owner]++, + vars.sig.deadline + ) + ) + ), + owner, + vars.sig + ); + } + _setDispatcher(vars.profileId, vars.dispatcher); + } + + /// @inheritdoc ILensHub + function setProfileImageURI(uint256 profileId, string calldata imageURI) + external + override + whenNotPaused + { + _validateCallerIsProfileOwnerOrDispatcher(profileId); + _setProfileImageURI(profileId, imageURI); + } + + /// @inheritdoc ILensHub + function setProfileImageURIWithSig(DataTypes.SetProfileImageURIWithSigData calldata vars) + external + override + whenNotPaused + { + address owner = ownerOf(vars.profileId); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + SET_PROFILE_IMAGE_URI_WITH_SIG_TYPEHASH, + vars.profileId, + keccak256(bytes(vars.imageURI)), + sigNonces[owner]++, + vars.sig.deadline + ) + ) + ), + owner, + vars.sig + ); + } + _setProfileImageURI(vars.profileId, vars.imageURI); + } + + /// @inheritdoc ILensHub + function setFollowNFTURI(uint256 profileId, string calldata followNFTURI) + external + override + whenNotPaused + { + _validateCallerIsProfileOwnerOrDispatcher(profileId); + _setFollowNFTURI(profileId, followNFTURI); + } + + /// @inheritdoc ILensHub + function setFollowNFTURIWithSig(DataTypes.SetFollowNFTURIWithSigData calldata vars) + external + override + whenNotPaused + { + address owner = ownerOf(vars.profileId); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + SET_FOLLOW_NFT_URI_WITH_SIG_TYPEHASH, + vars.profileId, + keccak256(bytes(vars.followNFTURI)), + sigNonces[owner]++, + vars.sig.deadline + ) + ) + ), + owner, + vars.sig + ); + } + _setFollowNFTURI(vars.profileId, vars.followNFTURI); + } + + /// @inheritdoc ILensHub + function post(DataTypes.PostData calldata vars) + external + override + whenPublishingEnabled + returns (uint256) + { + _validateCallerIsProfileOwnerOrDispatcher(vars.profileId); + return + _createPost( + vars.profileId, + vars.contentURI, + vars.collectModule, + vars.collectModuleInitData, + vars.referenceModule, + vars.referenceModuleInitData + ); + } + + /// @inheritdoc ILensHub + function postWithSig(DataTypes.PostWithSigData calldata vars) + external + override + whenPublishingEnabled + returns (uint256) + { + address owner = ownerOf(vars.profileId); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + POST_WITH_SIG_TYPEHASH, + vars.profileId, + keccak256(bytes(vars.contentURI)), + vars.collectModule, + keccak256(vars.collectModuleInitData), + vars.referenceModule, + keccak256(vars.referenceModuleInitData), + sigNonces[owner]++, + vars.sig.deadline + ) + ) + ), + owner, + vars.sig + ); + } + return + _createPost( + vars.profileId, + vars.contentURI, + vars.collectModule, + vars.collectModuleInitData, + vars.referenceModule, + vars.referenceModuleInitData + ); + } + + /// @inheritdoc ILensHub + function comment(DataTypes.CommentData calldata vars) + external + override + whenPublishingEnabled + returns (uint256) + { + _validateCallerIsProfileOwnerOrDispatcher(vars.profileId); + return _createComment(vars); + } + + /// @inheritdoc ILensHub + function commentWithSig(DataTypes.CommentWithSigData calldata vars) + external + override + whenPublishingEnabled + returns (uint256) + { + address owner = ownerOf(vars.profileId); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + COMMENT_WITH_SIG_TYPEHASH, + vars.profileId, + keccak256(bytes(vars.contentURI)), + vars.profileIdPointed, + vars.pubIdPointed, + keccak256(vars.referenceModuleData), + vars.collectModule, + keccak256(vars.collectModuleInitData), + vars.referenceModule, + keccak256(vars.referenceModuleInitData), + sigNonces[owner]++, + vars.sig.deadline + ) + ) + ), + owner, + vars.sig + ); + } + return + _createComment( + DataTypes.CommentData( + vars.profileId, + vars.contentURI, + vars.profileIdPointed, + vars.pubIdPointed, + vars.referenceModuleData, + vars.collectModule, + vars.collectModuleInitData, + vars.referenceModule, + vars.referenceModuleInitData + ) + ); + } + + /// @inheritdoc ILensHub + function mirror(DataTypes.MirrorData calldata vars) + external + override + whenPublishingEnabled + returns (uint256) + { + _validateCallerIsProfileOwnerOrDispatcher(vars.profileId); + return _createMirror(vars); + } + + /// @inheritdoc ILensHub + function mirrorWithSig(DataTypes.MirrorWithSigData calldata vars) + external + override + whenPublishingEnabled + returns (uint256) + { + address owner = ownerOf(vars.profileId); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + MIRROR_WITH_SIG_TYPEHASH, + vars.profileId, + vars.profileIdPointed, + vars.pubIdPointed, + keccak256(vars.referenceModuleData), + vars.referenceModule, + keccak256(vars.referenceModuleInitData), + sigNonces[owner]++, + vars.sig.deadline + ) + ) + ), + owner, + vars.sig + ); + } + return + _createMirror( + DataTypes.MirrorData( + vars.profileId, + vars.profileIdPointed, + vars.pubIdPointed, + vars.referenceModuleData, + vars.referenceModule, + vars.referenceModuleInitData + ) + ); + } + + /** + * @notice Burns a profile, this maintains the profile data struct, but deletes the + * handle hash to profile ID mapping value. + * + * NOTE: This overrides the LensNFTBase contract's `burn()` function and calls it to fully burn + * the NFT. + */ + function burn(uint256 tokenId) public override whenNotPaused { + super.burn(tokenId); + _clearHandleHash(tokenId); + } + + /** + * @notice Burns a profile with a signature, this maintains the profile data struct, but deletes the + * handle hash to profile ID mapping value. + * + * NOTE: This overrides the LensNFTBase contract's `burnWithSig()` function and calls it to fully burn + * the NFT. + */ + function burnWithSig(uint256 tokenId, DataTypes.EIP712Signature calldata sig) + public + override + whenNotPaused + { + super.burnWithSig(tokenId, sig); + _clearHandleHash(tokenId); + } + + /// *************************************** + /// *****PROFILE INTERACTION FUNCTIONS***** + /// *************************************** + + /// @inheritdoc ILensHub + function follow(uint256[] calldata profileIds, bytes[] calldata datas) + external + override + whenNotPaused + returns (uint256[] memory) + { + return + InteractionLogic.follow( + msg.sender, + profileIds, + datas, + _profileById, + _profileIdByHandleHash + ); + } + + /// @inheritdoc ILensHub + function followWithSig(DataTypes.FollowWithSigData calldata vars) + external + override + whenNotPaused + returns (uint256[] memory) + { + uint256 dataLength = vars.datas.length; + bytes32[] memory dataHashes = new bytes32[](dataLength); + for (uint256 i = 0; i < dataLength; ) { + dataHashes[i] = keccak256(vars.datas[i]); + unchecked { + ++i; + } + } + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + FOLLOW_WITH_SIG_TYPEHASH, + keccak256(abi.encodePacked(vars.profileIds)), + keccak256(abi.encodePacked(dataHashes)), + sigNonces[vars.follower]++, + vars.sig.deadline + ) + ) + ), + vars.follower, + vars.sig + ); + } + return + InteractionLogic.follow( + vars.follower, + vars.profileIds, + vars.datas, + _profileById, + _profileIdByHandleHash + ); + } + + /// @inheritdoc ILensHub + function collect( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override whenNotPaused returns (uint256) { + return + InteractionLogic.collect( + msg.sender, + profileId, + pubId, + data, + COLLECT_NFT_IMPL, + _pubByIdByProfile, + _profileById + ); + } + + /// @inheritdoc ILensHub + function collectWithSig(DataTypes.CollectWithSigData calldata vars) + external + override + whenNotPaused + returns (uint256) + { + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + COLLECT_WITH_SIG_TYPEHASH, + vars.profileId, + vars.pubId, + keccak256(vars.data), + sigNonces[vars.collector]++, + vars.sig.deadline + ) + ) + ), + vars.collector, + vars.sig + ); + } + return + InteractionLogic.collect( + vars.collector, + vars.profileId, + vars.pubId, + vars.data, + COLLECT_NFT_IMPL, + _pubByIdByProfile, + _profileById + ); + } + + /// @inheritdoc ILensHub + function emitFollowNFTTransferEvent( + uint256 profileId, + uint256 followNFTId, + address from, + address to + ) external override { + address expectedFollowNFT = _profileById[profileId].followNFT; + if (msg.sender != expectedFollowNFT) revert Errors.CallerNotFollowNFT(); + emit Events.FollowNFTTransferred(profileId, followNFTId, from, to, block.timestamp); + } + + /// @inheritdoc ILensHub + function emitCollectNFTTransferEvent( + uint256 profileId, + uint256 pubId, + uint256 collectNFTId, + address from, + address to + ) external override { + address expectedCollectNFT = _pubByIdByProfile[profileId][pubId].collectNFT; + if (msg.sender != expectedCollectNFT) revert Errors.CallerNotCollectNFT(); + emit Events.CollectNFTTransferred( + profileId, + pubId, + collectNFTId, + from, + to, + block.timestamp + ); + } + + /// ********************************* + /// *****EXTERNAL VIEW FUNCTIONS***** + /// ********************************* + + /// @inheritdoc ILensHub + function isProfileCreatorWhitelisted(address profileCreator) + external + view + override + returns (bool) + { + return _profileCreatorWhitelisted[profileCreator]; + } + + /// @inheritdoc ILensHub + function defaultProfile(address wallet) external view override returns (uint256) { + return _defaultProfileByAddress[wallet]; + } + + /// @inheritdoc ILensHub + function isFollowModuleWhitelisted(address followModule) external view override returns (bool) { + return _followModuleWhitelisted[followModule]; + } + + /// @inheritdoc ILensHub + function isReferenceModuleWhitelisted(address referenceModule) + external + view + override + returns (bool) + { + return _referenceModuleWhitelisted[referenceModule]; + } + + /// @inheritdoc ILensHub + function isCollectModuleWhitelisted(address collectModule) + external + view + override + returns (bool) + { + return _collectModuleWhitelisted[collectModule]; + } + + /// @inheritdoc ILensHub + function getGovernance() external view override returns (address) { + return _governance; + } + + /// @inheritdoc ILensHub + function getDispatcher(uint256 profileId) external view override returns (address) { + return _dispatcherByProfile[profileId]; + } + + /// @inheritdoc ILensHub + function getPubCount(uint256 profileId) external view override returns (uint256) { + return _profileById[profileId].pubCount; + } + + /// @inheritdoc ILensHub + function getFollowNFT(uint256 profileId) external view override returns (address) { + return _profileById[profileId].followNFT; + } + + /// @inheritdoc ILensHub + function getFollowNFTURI(uint256 profileId) external view override returns (string memory) { + return _profileById[profileId].followNFTURI; + } + + /// @inheritdoc ILensHub + function getCollectNFT(uint256 profileId, uint256 pubId) + external + view + override + returns (address) + { + return _pubByIdByProfile[profileId][pubId].collectNFT; + } + + /// @inheritdoc ILensHub + function getFollowModule(uint256 profileId) external view override returns (address) { + return _profileById[profileId].followModule; + } + + /// @inheritdoc ILensHub + function getCollectModule(uint256 profileId, uint256 pubId) + external + view + override + returns (address) + { + return _pubByIdByProfile[profileId][pubId].collectModule; + } + + /// @inheritdoc ILensHub + function getReferenceModule(uint256 profileId, uint256 pubId) + external + view + override + returns (address) + { + return _pubByIdByProfile[profileId][pubId].referenceModule; + } + + /// @inheritdoc ILensHub + function getHandle(uint256 profileId) external view override returns (string memory) { + return _profileById[profileId].handle; + } + + /// @inheritdoc ILensHub + function getPubPointer(uint256 profileId, uint256 pubId) + external + view + override + returns (uint256, uint256) + { + uint256 profileIdPointed = _pubByIdByProfile[profileId][pubId].profileIdPointed; + uint256 pubIdPointed = _pubByIdByProfile[profileId][pubId].pubIdPointed; + return (profileIdPointed, pubIdPointed); + } + + /// @inheritdoc ILensHub + function getContentURI(uint256 profileId, uint256 pubId) + external + view + override + returns (string memory) + { + (uint256 rootProfileId, uint256 rootPubId, ) = Helpers.getPointedIfMirror( + profileId, + pubId, + _pubByIdByProfile + ); + return _pubByIdByProfile[rootProfileId][rootPubId].contentURI; + } + + /// @inheritdoc ILensHub + function getProfileIdByHandle(string calldata handle) external view override returns (uint256) { + bytes32 handleHash = keccak256(bytes(handle)); + return _profileIdByHandleHash[handleHash]; + } + + /// @inheritdoc ILensHub + function getProfile(uint256 profileId) + external + view + override + returns (DataTypes.ProfileStruct memory) + { + return _profileById[profileId]; + } + + /// @inheritdoc ILensHub + function getPub(uint256 profileId, uint256 pubId) + external + view + override + returns (DataTypes.PublicationStruct memory) + { + return _pubByIdByProfile[profileId][pubId]; + } + + /// @inheritdoc ILensHub + function getPubType(uint256 profileId, uint256 pubId) + external + view + override + returns (DataTypes.PubType) + { + if (pubId == 0 || _profileById[profileId].pubCount < pubId) { + return DataTypes.PubType.Nonexistent; + } else if (_pubByIdByProfile[profileId][pubId].collectModule == address(0)) { + return DataTypes.PubType.Mirror; + } else if (_pubByIdByProfile[profileId][pubId].profileIdPointed == 0) { + return DataTypes.PubType.Post; + } else { + return DataTypes.PubType.Comment; + } + } + + /** + * @dev Overrides the ERC721 tokenURI function to return the associated URI with a given profile. + */ + function tokenURI(uint256 tokenId) public view override returns (string memory) { + address followNFT = _profileById[tokenId].followNFT; + return + ProfileTokenURILogic.getProfileTokenURI( + tokenId, + followNFT == address(0) ? 0 : IERC721Enumerable(followNFT).totalSupply(), + ownerOf(tokenId), + _profileById[tokenId].handle, + _profileById[tokenId].imageURI + ); + } + + /// @inheritdoc ILensHub + function getFollowNFTImpl() external view override returns (address) { + return FOLLOW_NFT_IMPL; + } + + /// @inheritdoc ILensHub + function getCollectNFTImpl() external view override returns (address) { + return COLLECT_NFT_IMPL; + } + + /// **************************** + /// *****INTERNAL FUNCTIONS***** + /// **************************** + + function _setGovernance(address newGovernance) internal { + address prevGovernance = _governance; + _governance = newGovernance; + emit Events.GovernanceSet(msg.sender, prevGovernance, newGovernance, block.timestamp); + } + + function _createPost( + uint256 profileId, + string memory contentURI, + address collectModule, + bytes memory collectModuleData, + address referenceModule, + bytes memory referenceModuleData + ) internal returns (uint256) { + unchecked { + uint256 pubId = ++_profileById[profileId].pubCount; + PublishingLogic.createPost( + profileId, + contentURI, + collectModule, + collectModuleData, + referenceModule, + referenceModuleData, + pubId, + _pubByIdByProfile, + _collectModuleWhitelisted, + _referenceModuleWhitelisted + ); + return pubId; + } + } + + /* + * If the profile ID is zero, this is the equivalent of "unsetting" a default profile. + * Note that the wallet address should either be the message sender or validated via a signature + * prior to this function call. + */ + function _setDefaultProfile(address wallet, uint256 profileId) internal { + if (profileId > 0 && wallet != ownerOf(profileId)) revert Errors.NotProfileOwner(); + + _defaultProfileByAddress[wallet] = profileId; + + emit Events.DefaultProfileSet(wallet, profileId, block.timestamp); + } + + function _createComment(DataTypes.CommentData memory vars) internal returns (uint256) { + unchecked { + uint256 pubId = ++_profileById[vars.profileId].pubCount; + PublishingLogic.createComment( + vars, + pubId, + _profileById, + _pubByIdByProfile, + _collectModuleWhitelisted, + _referenceModuleWhitelisted + ); + return pubId; + } + } + + function _createMirror(DataTypes.MirrorData memory vars) internal returns (uint256) { + unchecked { + uint256 pubId = ++_profileById[vars.profileId].pubCount; + PublishingLogic.createMirror( + vars, + pubId, + _pubByIdByProfile, + _referenceModuleWhitelisted + ); + return pubId; + } + } + + function _setDispatcher(uint256 profileId, address dispatcher) internal { + _dispatcherByProfile[profileId] = dispatcher; + emit Events.DispatcherSet(profileId, dispatcher, block.timestamp); + } + + function _setProfileImageURI(uint256 profileId, string calldata imageURI) internal { + if (bytes(imageURI).length > Constants.MAX_PROFILE_IMAGE_URI_LENGTH) + revert Errors.ProfileImageURILengthInvalid(); + _profileById[profileId].imageURI = imageURI; + emit Events.ProfileImageURISet(profileId, imageURI, block.timestamp); + } + + function _setFollowNFTURI(uint256 profileId, string calldata followNFTURI) internal { + _profileById[profileId].followNFTURI = followNFTURI; + emit Events.FollowNFTURISet(profileId, followNFTURI, block.timestamp); + } + + function _clearHandleHash(uint256 profileId) internal { + bytes32 handleHash = keccak256(bytes(_profileById[profileId].handle)); + _profileIdByHandleHash[handleHash] = 0; + } + + function _beforeTokenTransfer( + address from, + address to, + uint256 tokenId + ) internal override whenNotPaused { + if (_dispatcherByProfile[tokenId] != address(0)) { + _setDispatcher(tokenId, address(0)); + } + + if (_defaultProfileByAddress[from] == tokenId) { + _defaultProfileByAddress[from] = 0; + } + + super._beforeTokenTransfer(from, to, tokenId); + } + + function _validateCallerIsProfileOwnerOrDispatcher(uint256 profileId) internal view { + if (msg.sender == ownerOf(profileId) || msg.sender == _dispatcherByProfile[profileId]) { + return; + } + revert Errors.NotProfileOwnerOrDispatcher(); + } + + function _validateCallerIsProfileOwner(uint256 profileId) internal view { + if (msg.sender != ownerOf(profileId)) revert Errors.NotProfileOwner(); + } + + function _validateCallerIsGovernance() internal view { + if (msg.sender != _governance) revert Errors.NotGovernance(); + } + + function getRevision() internal pure virtual override returns (uint256) { + return REVISION; + } +} diff --git a/lens-protocol/core/contracts/core/base/ERC721Enumerable.sol b/lens-protocol/core/contracts/core/base/ERC721Enumerable.sol new file mode 100644 index 0000000..7ceb81a --- /dev/null +++ b/lens-protocol/core/contracts/core/base/ERC721Enumerable.sol @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import './ERC721Time.sol'; +import '@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol'; + +/** + * @dev This implements an optional extension of {ERC721} defined in the EIP that adds + * enumerability of all the token ids in the contract as well as all token ids owned by each + * account. + * + * NOTE: Modified from Openzeppelin to inherit from a modified ERC721 contract. + */ +abstract contract ERC721Enumerable is ERC721Time, IERC721Enumerable { + // Mapping from owner to list of owned token IDs + mapping(address => mapping(uint256 => uint256)) private _ownedTokens; + + // Mapping from token ID to index of the owner tokens list + mapping(uint256 => uint256) private _ownedTokensIndex; + + // Array with all token ids, used for enumeration + uint256[] private _allTokens; + + // Mapping from token id to position in the allTokens array + mapping(uint256 => uint256) private _allTokensIndex; + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(IERC165, ERC721Time) + returns (bool) + { + return + interfaceId == type(IERC721Enumerable).interfaceId || + super.supportsInterface(interfaceId); + } + + /** + * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. + */ + function tokenOfOwnerByIndex(address owner, uint256 index) + public + view + virtual + override + returns (uint256) + { + require(index < ERC721Time.balanceOf(owner), 'ERC721Enumerable: owner index out of bounds'); + return _ownedTokens[owner][index]; + } + + /** + * @dev See {IERC721Enumerable-totalSupply}. + */ + function totalSupply() public view virtual override returns (uint256) { + return _allTokens.length; + } + + /** + * @dev See {IERC721Enumerable-tokenByIndex}. + */ + function tokenByIndex(uint256 index) public view virtual override returns (uint256) { + require( + index < ERC721Enumerable.totalSupply(), + 'ERC721Enumerable: global index out of bounds' + ); + return _allTokens[index]; + } + + /** + * @dev Hook that is called before any token transfer. This includes minting + * and burning. + * + * Calling conditions: + * + * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be + * transferred to `to`. + * - When `from` is zero, `tokenId` will be minted for `to`. + * - When `to` is zero, ``from``'s `tokenId` will be burned. + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 tokenId + ) internal virtual override { + super._beforeTokenTransfer(from, to, tokenId); + + if (from == address(0)) { + _addTokenToAllTokensEnumeration(tokenId); + } else if (from != to) { + _removeTokenFromOwnerEnumeration(from, tokenId); + } + if (to == address(0)) { + _removeTokenFromAllTokensEnumeration(tokenId); + } else if (to != from) { + _addTokenToOwnerEnumeration(to, tokenId); + } + } + + /** + * @dev Private function to add a token to this extension's ownership-tracking data structures. + * @param to address representing the new owner of the given token ID + * @param tokenId uint256 ID of the token to be added to the tokens list of the given address + */ + function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { + uint256 length = ERC721Time.balanceOf(to); + _ownedTokens[to][length] = tokenId; + _ownedTokensIndex[tokenId] = length; + } + + /** + * @dev Private function to add a token to this extension's token tracking data structures. + * @param tokenId uint256 ID of the token to be added to the tokens list + */ + function _addTokenToAllTokensEnumeration(uint256 tokenId) private { + _allTokensIndex[tokenId] = _allTokens.length; + _allTokens.push(tokenId); + } + + /** + * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that + * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for + * gas optimizations e.g. when performing a transfer operation (avoiding double writes). + * This has O(1) time complexity, but alters the order of the _ownedTokens array. + * @param from address representing the previous owner of the given token ID + * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address + */ + function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { + // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + + uint256 lastTokenIndex = ERC721Time.balanceOf(from) - 1; + uint256 tokenIndex = _ownedTokensIndex[tokenId]; + + // When the token to delete is the last token, the swap operation is unnecessary + if (tokenIndex != lastTokenIndex) { + uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; + + _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + } + + // This also deletes the contents at the last position of the array + delete _ownedTokensIndex[tokenId]; + delete _ownedTokens[from][lastTokenIndex]; + } + + /** + * @dev Private function to remove a token from this extension's token tracking data structures. + * This has O(1) time complexity, but alters the order of the _allTokens array. + * @param tokenId uint256 ID of the token to be removed from the tokens list + */ + function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { + // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + + uint256 lastTokenIndex = _allTokens.length - 1; + uint256 tokenIndex = _allTokensIndex[tokenId]; + + // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so + // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding + // an 'if' statement (like in _removeTokenFromOwnerEnumeration) + uint256 lastTokenId = _allTokens[lastTokenIndex]; + + _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + + // This also deletes the contents at the last position of the array + delete _allTokensIndex[tokenId]; + _allTokens.pop(); + } +} diff --git a/lens-protocol/core/contracts/core/base/ERC721Time.sol b/lens-protocol/core/contracts/core/base/ERC721Time.sol new file mode 100644 index 0000000..b3b3845 --- /dev/null +++ b/lens-protocol/core/contracts/core/base/ERC721Time.sol @@ -0,0 +1,496 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import './IERC721Time.sol'; +import '@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol'; +import '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol'; +import '@openzeppelin/contracts/utils/Address.sol'; +import '@openzeppelin/contracts/utils/Context.sol'; +import '@openzeppelin/contracts/utils/Strings.sol'; +import '@openzeppelin/contracts/utils/introspection/ERC165.sol'; + +/** + * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including + * the Metadata extension, but not including the Enumerable extension, which is available separately as + * {ERC721Enumerable}. + * + * Modifications: + * 1. Refactored _operatorApprovals setter into an internal function to allow meta-transactions. + * 2. Constructor replaced with an initializer. + * 3. Mint timestamp is now stored in a TokenData struct alongside the owner address. + */ +abstract contract ERC721Time is Context, ERC165, IERC721Time, IERC721Metadata { + using Address for address; + using Strings for uint256; + + // Token name + string private _name; + + // Token symbol + string private _symbol; + + // Mapping from token ID to token Data (owner address and mint timestamp uint96), this + // replaces the original mapping(uint256 => address) private _owners; + mapping(uint256 => IERC721Time.TokenData) private _tokenData; + + // Mapping owner address to token count + mapping(address => uint256) private _balances; + + // Mapping from token ID to approved address + mapping(uint256 => address) private _tokenApprovals; + + // Mapping from owner to operator approvals + mapping(address => mapping(address => bool)) private _operatorApprovals; + + /** + * @dev Initializes the ERC721 name and symbol. + * + * @param name The name to set. + * @param symbol The symbol to set. + */ + function __ERC721_Init(string calldata name, string calldata symbol) internal { + _name = name; + _symbol = symbol; + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC165, IERC165) + returns (bool) + { + return + interfaceId == type(IERC721).interfaceId || + interfaceId == type(IERC721Metadata).interfaceId || + super.supportsInterface(interfaceId); + } + + /** + * @dev See {IERC721-balanceOf}. + */ + function balanceOf(address owner) public view virtual override returns (uint256) { + require(owner != address(0), 'ERC721: balance query for the zero address'); + return _balances[owner]; + } + + /** + * @dev See {IERC721-ownerOf}. + */ + function ownerOf(uint256 tokenId) public view virtual override returns (address) { + address owner = _tokenData[tokenId].owner; + require(owner != address(0), 'ERC721: owner query for nonexistent token'); + return owner; + } + + /** + * @dev See {IERC721Time-mintTimestampOf} + */ + function mintTimestampOf(uint256 tokenId) public view virtual override returns (uint256) { + uint96 mintTimestamp = _tokenData[tokenId].mintTimestamp; + require(mintTimestamp != 0, 'ERC721: mint timestamp query for nonexistent token'); + return mintTimestamp; + } + + /** + * @dev See {IERC721Time-mintTimestampOf} + */ + function tokenDataOf(uint256 tokenId) + public + view + virtual + override + returns (IERC721Time.TokenData memory) + { + require(_exists(tokenId), 'ERC721: token data query for nonexistent token'); + return _tokenData[tokenId]; + } + + /** + * @dev See {IERC721Time-exists} + */ + function exists(uint256 tokenId) public view virtual override returns (bool) { + return _exists(tokenId); + } + + /** + * @dev See {IERC721Metadata-name}. + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev See {IERC721Metadata-symbol}. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev See {IERC721Metadata-tokenURI}. + */ + function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { + require(_exists(tokenId), 'ERC721Metadata: URI query for nonexistent token'); + + string memory baseURI = _baseURI(); + return + bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ''; + } + + /** + * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each + * token will be the concatenation of the `baseURI` and the `tokenId`. Empty + * by default, can be overriden in child contracts. + */ + function _baseURI() internal view virtual returns (string memory) { + return ''; + } + + /** + * @dev See {IERC721-approve}. + */ + function approve(address to, uint256 tokenId) public virtual override { + address owner = ERC721Time.ownerOf(tokenId); + require(to != owner, 'ERC721: approval to current owner'); + + require( + _msgSender() == owner || isApprovedForAll(owner, _msgSender()), + 'ERC721: approve caller is not owner nor approved for all' + ); + + _approve(to, tokenId); + } + + /** + * @dev See {IERC721-getApproved}. + */ + function getApproved(uint256 tokenId) public view virtual override returns (address) { + require(_exists(tokenId), 'ERC721: approved query for nonexistent token'); + + return _tokenApprovals[tokenId]; + } + + /** + * @dev See {IERC721-setApprovalForAll}. + */ + function setApprovalForAll(address operator, bool approved) public virtual override { + require(operator != _msgSender(), 'ERC721: approve to caller'); + + _setOperatorApproval(_msgSender(), operator, approved); + } + + /** + * @dev See {IERC721-isApprovedForAll}. + */ + function isApprovedForAll(address owner, address operator) + public + view + virtual + override + returns (bool) + { + return _operatorApprovals[owner][operator]; + } + + /** + * @dev See {IERC721-transferFrom}. + */ + function transferFrom( + address from, + address to, + uint256 tokenId + ) public virtual override { + //solhint-disable-next-line max-line-length + require( + _isApprovedOrOwner(_msgSender(), tokenId), + 'ERC721: transfer caller is not owner nor approved' + ); + + _transfer(from, to, tokenId); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId + ) public virtual override { + safeTransferFrom(from, to, tokenId, ''); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId, + bytes memory _data + ) public virtual override { + require( + _isApprovedOrOwner(_msgSender(), tokenId), + 'ERC721: transfer caller is not owner nor approved' + ); + _safeTransfer(from, to, tokenId, _data); + } + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * `_data` is additional data, it has no specified format and it is sent in call to `to`. + * + * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. + * implement alternative mechanisms to perform token transfer, such as signature-based. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeTransfer( + address from, + address to, + uint256 tokenId, + bytes memory _data + ) internal virtual { + _transfer(from, to, tokenId); + require( + _checkOnERC721Received(from, to, tokenId, _data), + 'ERC721: transfer to non ERC721Receiver implementer' + ); + } + + /** + * @dev Returns whether `tokenId` exists. + * + * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. + * + * Tokens start existing when they are minted (`_mint`), + * and stop existing when they are burned (`_burn`). + */ + function _exists(uint256 tokenId) internal view virtual returns (bool) { + return _tokenData[tokenId].owner != address(0); + } + + /** + * @dev Returns whether `spender` is allowed to manage `tokenId`. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function _isApprovedOrOwner(address spender, uint256 tokenId) + internal + view + virtual + returns (bool) + { + require(_exists(tokenId), 'ERC721: operator query for nonexistent token'); + address owner = ERC721Time.ownerOf(tokenId); + return (spender == owner || + getApproved(tokenId) == spender || + isApprovedForAll(owner, spender)); + } + + /** + * @dev Safely mints `tokenId` and transfers it to `to`. + * + * Requirements: + * + * - `tokenId` must not exist. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeMint(address to, uint256 tokenId) internal virtual { + _safeMint(to, tokenId, ''); + } + + /** + * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is + * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. + */ + function _safeMint( + address to, + uint256 tokenId, + bytes memory _data + ) internal virtual { + _mint(to, tokenId); + require( + _checkOnERC721Received(address(0), to, tokenId, _data), + 'ERC721: transfer to non ERC721Receiver implementer' + ); + } + + /** + * @dev Mints `tokenId` and transfers it to `to`. + * + * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible + * + * Requirements: + * + * - `tokenId` must not exist. + * - `to` cannot be the zero address. + * + * Emits a {Transfer} event. + */ + function _mint(address to, uint256 tokenId) internal virtual { + require(to != address(0), 'ERC721: mint to the zero address'); + require(!_exists(tokenId), 'ERC721: token already minted'); + + _beforeTokenTransfer(address(0), to, tokenId); + + _balances[to] += 1; + _tokenData[tokenId].owner = to; + _tokenData[tokenId].mintTimestamp = uint96(block.timestamp); + + emit Transfer(address(0), to, tokenId); + } + + /** + * @dev Destroys `tokenId`. + * The approval is cleared when the token is burned. + * + * Requirements: + * + * - `tokenId` must exist. + * + * Emits a {Transfer} event. + */ + function _burn(uint256 tokenId) internal virtual { + address owner = ERC721Time.ownerOf(tokenId); + + _beforeTokenTransfer(owner, address(0), tokenId); + + // Clear approvals + _approve(address(0), tokenId); + + _balances[owner] -= 1; + delete _tokenData[tokenId]; + + emit Transfer(owner, address(0), tokenId); + } + + /** + * @dev Transfers `tokenId` from `from` to `to`. + * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * + * Emits a {Transfer} event. + */ + function _transfer( + address from, + address to, + uint256 tokenId + ) internal virtual { + require(ERC721Time.ownerOf(tokenId) == from, 'ERC721: transfer of token that is not own'); + require(to != address(0), 'ERC721: transfer to the zero address'); + + _beforeTokenTransfer(from, to, tokenId); + + // Clear approvals from the previous owner + _approve(address(0), tokenId); + + _balances[from] -= 1; + _balances[to] += 1; + _tokenData[tokenId].owner = to; + + emit Transfer(from, to, tokenId); + } + + /** + * @dev Approve `to` to operate on `tokenId` + * + * Emits a {Approval} event. + */ + function _approve(address to, uint256 tokenId) internal virtual { + _tokenApprovals[tokenId] = to; + emit Approval(ERC721Time.ownerOf(tokenId), to, tokenId); + } + + /** + * @dev Refactored from the original OZ ERC721 implementation: approve or revoke approval from + * `operator` to operate on all tokens owned by `owner`. + * + * Emits a {ApprovalForAll} event. + */ + function _setOperatorApproval( + address owner, + address operator, + bool approved + ) internal virtual { + _operatorApprovals[owner][operator] = approved; + emit ApprovalForAll(owner, operator, approved); + } + + /** + * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. + * The call is not executed if the target address is not a contract. + * + * @param from address representing the previous owner of the given token ID + * @param to target address that will receive the tokens + * @param tokenId uint256 ID of the token to be transferred + * @param _data bytes optional data to send along with the call + * @return bool whether the call correctly returned the expected magic value + */ + function _checkOnERC721Received( + address from, + address to, + uint256 tokenId, + bytes memory _data + ) private returns (bool) { + if (to.isContract()) { + try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns ( + bytes4 retval + ) { + return retval == IERC721Receiver.onERC721Received.selector; + } catch (bytes memory reason) { + if (reason.length == 0) { + revert('ERC721: transfer to non ERC721Receiver implementer'); + } else { + assembly { + revert(add(32, reason), mload(reason)) + } + } + } + } else { + return true; + } + } + + /** + * @dev Hook that is called before any token transfer. This includes minting + * and burning. + * + * Calling conditions: + * + * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be + * transferred to `to`. + * - When `from` is zero, `tokenId` will be minted for `to`. + * - When `to` is zero, ``from``'s `tokenId` will be burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 tokenId + ) internal virtual {} +} diff --git a/lens-protocol/core/contracts/core/base/IERC721Time.sol b/lens-protocol/core/contracts/core/base/IERC721Time.sol new file mode 100644 index 0000000..df84f4f --- /dev/null +++ b/lens-protocol/core/contracts/core/base/IERC721Time.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @title IERC721Time + * @author Lens Protocol + * + * @notice This is an expansion of the IERC721 interface that includes a struct for token data, + * which contains the token owner and the mint timestamp as well as associated getters. + */ +interface IERC721Time is IERC721 { + /** + * @notice Contains the owner address and the mint timestamp for every NFT. + * + * Note: Instead of the owner address in the _tokenOwners private mapping, we now store it in the + * _tokenData mapping, alongside the unchanging mintTimestamp. + * + * @param owner The token owner. + * @param mintTimestamp The mint timestamp. + */ + struct TokenData { + address owner; + uint96 mintTimestamp; + } + + /** + * @notice Returns the mint timestamp associated with a given NFT, stored only once upon initial mint. + * + * @param tokenId The token ID of the NFT to query the mint timestamp for. + * + * @return uint256 mint timestamp, this is stored as a uint96 but returned as a uint256 to reduce unnecessary + * padding. + */ + function mintTimestampOf(uint256 tokenId) external view returns (uint256); + + /** + * @notice Returns the token data associated with a given NFT. This allows fetching the token owner and + * mint timestamp in a single call. + * + * @param tokenId The token ID of the NFT to query the token data for. + * + * @return TokenData token data struct containing both the owner address and the mint timestamp. + */ + function tokenDataOf(uint256 tokenId) external view returns (TokenData memory); + + /** + * @notice Returns whether a token with the given token ID exists. + * + * @param tokenId The token ID of the NFT to check existence for. + * + * @return bool True if the token exists. + */ + function exists(uint256 tokenId) external view returns (bool); +} diff --git a/lens-protocol/core/contracts/core/base/LensMultiState.sol b/lens-protocol/core/contracts/core/base/LensMultiState.sol new file mode 100644 index 0000000..e58f8f0 --- /dev/null +++ b/lens-protocol/core/contracts/core/base/LensMultiState.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Events} from '../../libraries/Events.sol'; +import {DataTypes} from '../../libraries/DataTypes.sol'; +import {Errors} from '../../libraries/Errors.sol'; + +/** + * @title LensMultiState + * + * @notice This is an abstract contract that implements internal LensHub state setting and validation. + * + * whenNotPaused: Either publishingPaused or Unpaused. + * whenPublishingEnabled: When Unpaused only. + */ +abstract contract LensMultiState { + DataTypes.ProtocolState private _state; + + modifier whenNotPaused() { + _validateNotPaused(); + _; + } + + modifier whenPublishingEnabled() { + _validatePublishingEnabled(); + _; + } + + /** + * @notice Returns the current protocol state. + * + * @return ProtocolState The Protocol state, an enum, where: + * 0: Unpaused + * 1: PublishingPaused + * 2: Paused + */ + function getState() external view returns (DataTypes.ProtocolState) { + return _state; + } + + function _setState(DataTypes.ProtocolState newState) internal { + DataTypes.ProtocolState prevState = _state; + _state = newState; + emit Events.StateSet(msg.sender, prevState, newState, block.timestamp); + } + + function _validatePublishingEnabled() internal view { + if (_state != DataTypes.ProtocolState.Unpaused) { + revert Errors.PublishingPaused(); + } + } + + function _validateNotPaused() internal view { + if (_state == DataTypes.ProtocolState.Paused) revert Errors.Paused(); + } +} diff --git a/lens-protocol/core/contracts/core/base/LensNFTBase.sol b/lens-protocol/core/contracts/core/base/LensNFTBase.sol new file mode 100644 index 0000000..d6b0a77 --- /dev/null +++ b/lens-protocol/core/contracts/core/base/LensNFTBase.sol @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ILensNFTBase} from '../../interfaces/ILensNFTBase.sol'; +import {Errors} from '../../libraries/Errors.sol'; +import {DataTypes} from '../../libraries/DataTypes.sol'; +import {Events} from '../../libraries/Events.sol'; +import {ERC721Time} from './ERC721Time.sol'; +import {ERC721Enumerable} from './ERC721Enumerable.sol'; + +/** + * @title LensNFTBase + * @author Lens Protocol + * + * @notice This is an abstract base contract to be inherited by other Lens Protocol NFTs, it includes + * the slightly modified ERC721Enumerable, which itself inherits from the ERC721Time-- which adds an + * internal operator approval setter, stores the mint timestamp for each token, and replaces the + * constructor with an initializer. + */ +abstract contract LensNFTBase is ERC721Enumerable, ILensNFTBase { + bytes32 internal constant EIP712_REVISION_HASH = keccak256('1'); + bytes32 internal constant PERMIT_TYPEHASH = + keccak256('Permit(address spender,uint256 tokenId,uint256 nonce,uint256 deadline)'); + bytes32 internal constant PERMIT_FOR_ALL_TYPEHASH = + keccak256( + 'PermitForAll(address owner,address operator,bool approved,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant BURN_WITH_SIG_TYPEHASH = + keccak256('BurnWithSig(uint256 tokenId,uint256 nonce,uint256 deadline)'); + bytes32 internal constant EIP712_DOMAIN_TYPEHASH = + keccak256( + 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)' + ); + + mapping(address => uint256) public sigNonces; + + /** + * @notice Initializer sets the name, symbol and the cached domain separator. + * + * NOTE: Inheritor contracts *must* call this function to initialize the name & symbol in the + * inherited ERC721 contract. + * + * @param name The name to set in the ERC721 contract. + * @param symbol The symbol to set in the ERC721 contract. + */ + function _initialize(string calldata name, string calldata symbol) internal { + ERC721Time.__ERC721_Init(name, symbol); + + emit Events.BaseInitialized(name, symbol, block.timestamp); + } + + /// @inheritdoc ILensNFTBase + function permit( + address spender, + uint256 tokenId, + DataTypes.EIP712Signature calldata sig + ) external override { + if (spender == address(0)) revert Errors.ZeroSpender(); + address owner = ownerOf(tokenId); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + PERMIT_TYPEHASH, + spender, + tokenId, + sigNonces[owner]++, + sig.deadline + ) + ) + ), + owner, + sig + ); + } + _approve(spender, tokenId); + } + + /// @inheritdoc ILensNFTBase + function permitForAll( + address owner, + address operator, + bool approved, + DataTypes.EIP712Signature calldata sig + ) external override { + if (operator == address(0)) revert Errors.ZeroSpender(); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + PERMIT_FOR_ALL_TYPEHASH, + owner, + operator, + approved, + sigNonces[owner]++, + sig.deadline + ) + ) + ), + owner, + sig + ); + } + _setOperatorApproval(owner, operator, approved); + } + + /// @inheritdoc ILensNFTBase + function getDomainSeparator() external view override returns (bytes32) { + return _calculateDomainSeparator(); + } + + /// @inheritdoc ILensNFTBase + function burn(uint256 tokenId) public virtual override { + if (!_isApprovedOrOwner(msg.sender, tokenId)) revert Errors.NotOwnerOrApproved(); + _burn(tokenId); + } + + /// @inheritdoc ILensNFTBase + function burnWithSig(uint256 tokenId, DataTypes.EIP712Signature calldata sig) + public + virtual + override + { + address owner = ownerOf(tokenId); + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + BURN_WITH_SIG_TYPEHASH, + tokenId, + sigNonces[owner]++, + sig.deadline + ) + ) + ), + owner, + sig + ); + } + _burn(tokenId); + } + + /** + * @dev Wrapper for ecrecover to reduce code size, used in meta-tx specific functions. + */ + function _validateRecoveredAddress( + bytes32 digest, + address expectedAddress, + DataTypes.EIP712Signature calldata sig + ) internal view { + if (sig.deadline < block.timestamp) revert Errors.SignatureExpired(); + address recoveredAddress = ecrecover(digest, sig.v, sig.r, sig.s); + if (recoveredAddress == address(0) || recoveredAddress != expectedAddress) + revert Errors.SignatureInvalid(); + } + + /** + * @dev Calculates EIP712 DOMAIN_SEPARATOR based on the current contract and chain ID. + */ + function _calculateDomainSeparator() internal view returns (bytes32) { + return + keccak256( + abi.encode( + EIP712_DOMAIN_TYPEHASH, + keccak256(bytes(name())), + EIP712_REVISION_HASH, + block.chainid, + address(this) + ) + ); + } + + /** + * @dev Calculates EIP712 digest based on the current DOMAIN_SEPARATOR. + * + * @param hashedMessage The message hash from which the digest should be calculated. + * + * @return bytes32 A 32-byte output representing the EIP712 digest. + */ + function _calculateDigest(bytes32 hashedMessage) internal view returns (bytes32) { + bytes32 digest; + unchecked { + digest = keccak256( + abi.encodePacked('\x19\x01', _calculateDomainSeparator(), hashedMessage) + ); + } + return digest; + } +} diff --git a/lens-protocol/core/contracts/core/modules/CarbonRetireBase.sol b/lens-protocol/core/contracts/core/modules/CarbonRetireBase.sol new file mode 100644 index 0000000..785921b --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/CarbonRetireBase.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +import '@openzeppelin/contracts/utils/Strings.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; + +import {Errors} from '../../libraries/Errors.sol'; +import {IKlimaInfinity} from '../../interfaces/IKlimaInfinity.sol'; + +/** + * @title CarbonRetireBase + * @author + * + * @notice Abstract contract for carbon retirements + * + */ +abstract contract CarbonRetireBase { + using SafeERC20 for IERC20; + + // https://github.com/KlimaDAO/klimadao-solidity/blob/main/src/protocol/bonds/CarbonRetirementBondDepository.sol#L27 + address public immutable KLIMA_INFINITY; + + constructor(address _klimaInfinity) { + KLIMA_INFINITY = _klimaInfinity; + } + + /** + * @dev Performs carbon retirement + * + * @param collector The address that collects the post + * @param recipient The address that published the publication and receives the fee + * @param currency Fee currency of publication + * @param poolToken carbon pool token for retirement + * @param retirementAmount Amount of currency that goes into carbon retirement + */ + function _retireCarbon( + address collector, + address recipient, + address currency, + address poolToken, + uint256 retirementAmount, + string memory retiringEntityString, + string memory beneficiaryString, + string memory retirementMessage + ) internal { + // Transfer retirementAmount + // 2 transfers, because retirement function requires that token is received by msg.sender, + // which is collect module, not collector wallet (tx.origin). + IERC20(currency).safeTransferFrom(collector, address(this), retirementAmount); + IERC20(currency).safeTransfer(KLIMA_INFINITY, retirementAmount); + + // TODO: + // There's another safeTransferFrom inside retirement function, but with 0 amount + // https://github.com/KlimaDAO/klimadao-solidity/blob/88ff87907f8319407728b1488323ce9912cdd3ed/src/infinity/libraries/Token/LibTransfer.sol#L52 + // --> Will this require an approval by address(this)?? + // --> Does fromMode INTERNAL solve it? + + IKlimaInfinity(KLIMA_INFINITY).retireExactSourceDefault( + currency, + poolToken, + retirementAmount, + retiringEntityString, + recipient, + beneficiaryString, + retirementMessage, + 1 // TODO: Is 1 equal fromMode INTERNAL? https://github.com/KlimaDAO/klimadao-solidity/blob/88ff87907f8319407728b1488323ce9912cdd3ed/src/infinity/libraries/Token/LibTransfer.sol#L17 + ); + } + + /** + * @dev Check if retirementAggregator can swap from currency to poolToken. + * + * This function should not fail, but always return true/false + * Reason: processCollect should not fail, but instead lead to normal collect. + * + * @param sourceToken Address of the source token that is used to pay the retirement. + * @param poolToken Address of the carbon pool token that is used for retirement. + * @param amountIn Amount of the source token that is used for retirement. + * + * @return The ProfilePublicationData struct mapped to that publication. + */ + function checkRetirementSwapFeasibility( + address sourceToken, + address poolToken, + uint256 amountIn + ) public view returns (bool) { + if (!(amountIn > 0)) { + return false; + } + + // TODO: Check if desired behaviour is fulfilled: + // - _poolToken is not accepted by KlimaInfinity: return false + // - No swap path exists: return false + // - _poolToken accepted and swap path exists: return true + // - Check on liquidity/slippage/price_impact possible??? + + try + IKlimaInfinity(KLIMA_INFINITY).getRetireAmountSourceDefault( + sourceToken, + poolToken, + amountIn + ) + returns (uint256 amountOut) { + if (!(amountOut > 0)) { + return false; + } + } catch { + return false; + } + return true; + } +} diff --git a/lens-protocol/core/contracts/core/modules/FeeModuleBase.sol b/lens-protocol/core/contracts/core/modules/FeeModuleBase.sol new file mode 100644 index 0000000..a7c6c8f --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/FeeModuleBase.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Errors} from '../../libraries/Errors.sol'; +import {Events} from '../../libraries/Events.sol'; +import {IModuleGlobals} from '../../interfaces/IModuleGlobals.sol'; + +/** + * @title FeeModuleBase + * @author Lens Protocol + * + * @notice This is an abstract contract to be inherited from by modules that require basic fee functionality. It + * contains getters for module globals parameters as well as a validation function to check expected data. + */ +abstract contract FeeModuleBase { + uint16 internal constant BPS_MAX = 10000; + + address public immutable MODULE_GLOBALS; + + constructor(address moduleGlobals) { + if (moduleGlobals == address(0)) revert Errors.InitParamsInvalid(); + MODULE_GLOBALS = moduleGlobals; + emit Events.FeeModuleBaseConstructed(moduleGlobals, block.timestamp); + } + + function _currencyWhitelisted(address currency) internal view returns (bool) { + return IModuleGlobals(MODULE_GLOBALS).isCurrencyWhitelisted(currency); + } + + function _treasuryData() internal view returns (address, uint16) { + return IModuleGlobals(MODULE_GLOBALS).getTreasuryData(); + } + + function _validateDataIsExpected( + bytes calldata data, + address currency, + uint256 amount + ) internal pure { + (address decodedCurrency, uint256 decodedAmount) = abi.decode(data, (address, uint256)); + if (decodedAmount != amount || decodedCurrency != currency) + revert Errors.ModuleDataMismatch(); + } +} diff --git a/lens-protocol/core/contracts/core/modules/FollowValidationModuleBase.sol b/lens-protocol/core/contracts/core/modules/FollowValidationModuleBase.sol new file mode 100644 index 0000000..c1d3c40 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/FollowValidationModuleBase.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IFollowModule} from '../../interfaces/IFollowModule.sol'; +import {ILensHub} from '../../interfaces/ILensHub.sol'; +import {Errors} from '../../libraries/Errors.sol'; +import {Events} from '../../libraries/Events.sol'; +import {ModuleBase} from './ModuleBase.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @title FollowValidationModuleBase + * @author Lens Protocol + * + * @notice This abstract contract adds a simple non-specific follow validation function. + * + * NOTE: Both the `HUB` variable and `_checkFollowValidity()` function are exposed to inheriting + * contracts. + * + * NOTE: This is only compatible with COLLECT & REFERENCE MODULES. + */ +abstract contract FollowValidationModuleBase is ModuleBase { + /** + * @notice Validates whether a given user is following a given profile. + * + * @dev It will revert if the user is not following the profile except the case when the user is the profile owner. + * + * @param profileId The ID of the profile that should be followed by the given user. + * @param user The address of the user that should be following the given profile. + */ + function _checkFollowValidity(uint256 profileId, address user) internal view { + address followModule = ILensHub(HUB).getFollowModule(profileId); + bool isFollowing; + if (followModule != address(0)) { + isFollowing = IFollowModule(followModule).isFollowing(profileId, user, 0); + } else { + address followNFT = ILensHub(HUB).getFollowNFT(profileId); + isFollowing = followNFT != address(0) && IERC721(followNFT).balanceOf(user) != 0; + } + if (!isFollowing && IERC721(HUB).ownerOf(profileId) != user) { + revert Errors.FollowInvalid(); + } + } +} diff --git a/lens-protocol/core/contracts/core/modules/ModuleBase.sol b/lens-protocol/core/contracts/core/modules/ModuleBase.sol new file mode 100644 index 0000000..6e29a66 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/ModuleBase.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Errors} from '../../libraries/Errors.sol'; +import {Events} from '../../libraries/Events.sol'; + +/** + * @title ModuleBase + * @author Lens Protocol + * + * @notice This abstract contract adds a public `HUB` immutable to inheriting modules, as well as an + * `onlyHub` modifier. + */ +abstract contract ModuleBase { + address public immutable HUB; + + modifier onlyHub() { + if (msg.sender != HUB) revert Errors.NotHub(); + _; + } + + constructor(address hub) { + if (hub == address(0)) revert Errors.InitParamsInvalid(); + HUB = hub; + emit Events.ModuleBaseConstructed(hub, block.timestamp); + } +} diff --git a/lens-protocol/core/contracts/core/modules/ModuleGlobals.sol b/lens-protocol/core/contracts/core/modules/ModuleGlobals.sol new file mode 100644 index 0000000..16135da --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/ModuleGlobals.sol @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Errors} from '../../libraries/Errors.sol'; +import {Events} from '../../libraries/Events.sol'; +import {IModuleGlobals} from '../../interfaces/IModuleGlobals.sol'; + +/** + * @title ModuleGlobals + * @author Lens Protocol + * + * @notice This contract contains data relevant to Lens modules, such as the module governance address, treasury + * address and treasury fee BPS. + * + * NOTE: The reason we have an additional governance address instead of just fetching it from the hub is to + * allow the flexibility of using different governance executors. + */ +contract ModuleGlobals is IModuleGlobals { + uint16 internal constant BPS_MAX = 10000; + + mapping(address => bool) internal _currencyWhitelisted; + address internal _governance; + address internal _treasury; + uint16 internal _treasuryFee; + + modifier onlyGov() { + if (msg.sender != _governance) revert Errors.NotGovernance(); + _; + } + + /** + * @notice Initializes the governance, treasury and treasury fee amounts. + * + * @param governance The governance address which has additional control over setting certain parameters. + * @param treasury The treasury address to direct fees to. + * @param treasuryFee The treasury fee in BPS to levy on collects. + */ + constructor( + address governance, + address treasury, + uint16 treasuryFee + ) { + _setGovernance(governance); + _setTreasury(treasury); + _setTreasuryFee(treasuryFee); + } + + /// @inheritdoc IModuleGlobals + function setGovernance(address newGovernance) external override onlyGov { + _setGovernance(newGovernance); + } + + /// @inheritdoc IModuleGlobals + function setTreasury(address newTreasury) external override onlyGov { + _setTreasury(newTreasury); + } + + /// @inheritdoc IModuleGlobals + function setTreasuryFee(uint16 newTreasuryFee) external override onlyGov { + _setTreasuryFee(newTreasuryFee); + } + + /// @inheritdoc IModuleGlobals + function whitelistCurrency(address currency, bool toWhitelist) external override onlyGov { + _whitelistCurrency(currency, toWhitelist); + } + + /// @inheritdoc IModuleGlobals + function isCurrencyWhitelisted(address currency) external view override returns (bool) { + return _currencyWhitelisted[currency]; + } + + /// @inheritdoc IModuleGlobals + function getGovernance() external view override returns (address) { + return _governance; + } + + /// @inheritdoc IModuleGlobals + function getTreasury() external view override returns (address) { + return _treasury; + } + + /// @inheritdoc IModuleGlobals + function getTreasuryFee() external view override returns (uint16) { + return _treasuryFee; + } + + //@inheritdoc IModuleGlobals + function getTreasuryData() external view override returns (address, uint16) { + return (_treasury, _treasuryFee); + } + + function _setGovernance(address newGovernance) internal { + if (newGovernance == address(0)) revert Errors.InitParamsInvalid(); + address prevGovernance = _governance; + _governance = newGovernance; + emit Events.ModuleGlobalsGovernanceSet(prevGovernance, newGovernance, block.timestamp); + } + + function _setTreasury(address newTreasury) internal { + if (newTreasury == address(0)) revert Errors.InitParamsInvalid(); + address prevTreasury = _treasury; + _treasury = newTreasury; + emit Events.ModuleGlobalsTreasurySet(prevTreasury, newTreasury, block.timestamp); + } + + function _setTreasuryFee(uint16 newTreasuryFee) internal { + if (newTreasuryFee >= BPS_MAX / 2) revert Errors.InitParamsInvalid(); + uint16 prevTreasuryFee = _treasuryFee; + _treasuryFee = newTreasuryFee; + emit Events.ModuleGlobalsTreasuryFeeSet(prevTreasuryFee, newTreasuryFee, block.timestamp); + } + + function _whitelistCurrency(address currency, bool toWhitelist) internal { + if (currency == address(0)) revert Errors.InitParamsInvalid(); + bool prevWhitelisted = _currencyWhitelisted[currency]; + _currencyWhitelisted[currency] = toWhitelist; + emit Events.ModuleGlobalsCurrencyWhitelisted( + currency, + prevWhitelisted, + toWhitelist, + block.timestamp + ); + } +} diff --git a/lens-protocol/core/contracts/core/modules/collect/FeeCollectModule.sol b/lens-protocol/core/contracts/core/modules/collect/FeeCollectModule.sol new file mode 100644 index 0000000..c0641e9 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/collect/FeeCollectModule.sol @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ICollectModule} from '../../../interfaces/ICollectModule.sol'; +import {Errors} from '../../../libraries/Errors.sol'; +import {FeeModuleBase} from '../FeeModuleBase.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidationModuleBase} from '../FollowValidationModuleBase.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param amount The collecting cost associated with this publication. + * @param currency The currency associated with this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly Whether only followers should be able to collect. + */ +struct ProfilePublicationData { + uint256 amount; + address currency; + address recipient; + uint16 referralFee; + bool followerOnly; +} + +/** + * @title FeeCollectModule + * @author Lens Protocol + * + * @notice This is a simple Lens CollectModule implementation, inheriting from the ICollectModule interface and + * the FeeCollectModuleBase abstract contract. + * + * This module works by allowing unlimited collects for a publication at a given price. + */ +contract FeeCollectModule is FeeModuleBase, FollowValidationModuleBase, ICollectModule { + using SafeERC20 for IERC20; + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor(address hub, address moduleGlobals) FeeModuleBase(moduleGlobals) ModuleBase(hub) {} + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * + * @param profileId The token ID of the profile of the publisher, passed by the hub. + * @param pubId The publication ID of the newly created publication, passed by the hub. + * @param data The arbitrary data parameter, decoded into: + * uint256 amount: The currency total amount to levy. + * address currency: The currency address, must be internally whitelisted. + * address recipient: The custom recipient address to direct earnings to. + * uint16 referralFee: The referral fee to set. + * bool followerOnly: Whether only followers should be able to collect. + * + * @return bytes An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + ( + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly + ) = abi.decode(data, (uint256, address, address, uint16, bool)); + if ( + !_currencyWhitelisted(currency) || + recipient == address(0) || + referralFee > BPS_MAX || + amount == 0 + ) revert Errors.InitParamsInvalid(); + + _dataByPublicationByProfile[profileId][pubId].amount = amount; + _dataByPublicationByProfile[profileId][pubId].currency = currency; + _dataByPublicationByProfile[profileId][pubId].recipient = recipient; + _dataByPublicationByProfile[profileId][pubId].referralFee = referralFee; + _dataByPublicationByProfile[profileId][pubId].followerOnly = followerOnly; + + return data; + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower + * 2. Charging a fee + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external virtual override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return ProfilePublicationData The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + returns (ProfilePublicationData memory) + { + return _dataByPublicationByProfile[profileId][pubId]; + } + + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = amount - treasuryAmount; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (amount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = amount - treasuryAmount; + + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } +} diff --git a/lens-protocol/core/contracts/core/modules/collect/FreeCollectModule.sol b/lens-protocol/core/contracts/core/modules/collect/FreeCollectModule.sol new file mode 100644 index 0000000..836fc8f --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/collect/FreeCollectModule.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ICollectModule} from '../../../interfaces/ICollectModule.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidationModuleBase} from '../FollowValidationModuleBase.sol'; + +/** + * @title FreeCollectModule + * @author Lens Protocol + * + * @notice This is a simple Lens CollectModule implementation, inheriting from the ICollectModule interface. + * + * This module works by allowing all collects. + */ +contract FreeCollectModule is FollowValidationModuleBase, ICollectModule { + constructor(address hub) ModuleBase(hub) {} + + mapping(uint256 => mapping(uint256 => bool)) internal _followerOnlyByPublicationByProfile; + + /** + * @dev There is nothing needed at initialization. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + bool followerOnly = abi.decode(data, (bool)); + if (followerOnly) _followerOnlyByPublicationByProfile[profileId][pubId] = true; + return data; + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower, if needed + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external view override { + if (_followerOnlyByPublicationByProfile[profileId][pubId]) + _checkFollowValidity(profileId, collector); + } +} diff --git a/lens-protocol/core/contracts/core/modules/collect/LimitedFeeCollectModule.sol b/lens-protocol/core/contracts/core/modules/collect/LimitedFeeCollectModule.sol new file mode 100644 index 0000000..140d954 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/collect/LimitedFeeCollectModule.sol @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ICollectModule} from '../../../interfaces/ICollectModule.sol'; +import {Errors} from '../../../libraries/Errors.sol'; +import {FeeModuleBase} from '../FeeModuleBase.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidationModuleBase} from '../FollowValidationModuleBase.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param collectLimit The maximum number of collects for this publication. + * @param currentCollects The current number of collects for this publication. + * @param amount The collecting cost associated with this publication. + * @param currency The currency associated with this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly Whether only followers should be able to collect. + */ +struct ProfilePublicationData { + uint256 collectLimit; + uint256 currentCollects; + uint256 amount; + address currency; + address recipient; + uint16 referralFee; + bool followerOnly; +} + +/** + * @title LimitedFeeCollectModule + * @author Lens Protocol + * + * @notice This is a simple Lens CollectModule implementation, inheriting from the ICollectModule interface and + * the FeeCollectModuleBase abstract contract. + * + * This module works by allowing limited collects for a publication indefinitely. + */ +contract LimitedFeeCollectModule is FeeModuleBase, FollowValidationModuleBase, ICollectModule { + using SafeERC20 for IERC20; + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor(address hub, address moduleGlobals) FeeModuleBase(moduleGlobals) ModuleBase(hub) {} + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * + * @param profileId The profile ID of the publication to initialize this module for's publishing profile. + * @param pubId The publication ID of the publication to initialize this module for. + * @param data The arbitrary data parameter, decoded into: + * uint256 collectLimit: The maximum amount of collects. + * uint256 amount: The currency total amount to levy. + * address currency: The currency address, must be internally whitelisted. + * address recipient: The custom recipient address to direct earnings to. + * uint16 referralFee: The referral fee to set. + * bool followerOnly: Whether only followers should be able to collect. + * + * @return bytes An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + ( + uint256 collectLimit, + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly + ) = abi.decode(data, (uint256, uint256, address, address, uint16, bool)); + if ( + collectLimit == 0 || + !_currencyWhitelisted(currency) || + recipient == address(0) || + referralFee > BPS_MAX || + amount == 0 + ) revert Errors.InitParamsInvalid(); + + _dataByPublicationByProfile[profileId][pubId].collectLimit = collectLimit; + _dataByPublicationByProfile[profileId][pubId].amount = amount; + _dataByPublicationByProfile[profileId][pubId].currency = currency; + _dataByPublicationByProfile[profileId][pubId].recipient = recipient; + _dataByPublicationByProfile[profileId][pubId].referralFee = referralFee; + _dataByPublicationByProfile[profileId][pubId].followerOnly = followerOnly; + + return data; + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower + * 2. Ensuring the collect does not pass the collect limit + * 3. Charging a fee + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + if ( + _dataByPublicationByProfile[profileId][pubId].currentCollects >= + _dataByPublicationByProfile[profileId][pubId].collectLimit + ) { + revert Errors.MintLimitExceeded(); + } else { + ++_dataByPublicationByProfile[profileId][pubId].currentCollects; + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return ProfilePublicationData The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + returns (ProfilePublicationData memory) + { + return _dataByPublicationByProfile[profileId][pubId]; + } + + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = amount - treasuryAmount; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (amount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = amount - treasuryAmount; + + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } +} diff --git a/lens-protocol/core/contracts/core/modules/collect/LimitedTimedFeeCollectModule.sol b/lens-protocol/core/contracts/core/modules/collect/LimitedTimedFeeCollectModule.sol new file mode 100644 index 0000000..0417ce6 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/collect/LimitedTimedFeeCollectModule.sol @@ -0,0 +1,228 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ICollectModule} from '../../../interfaces/ICollectModule.sol'; +import {Errors} from '../../../libraries/Errors.sol'; +import {FeeModuleBase} from '../FeeModuleBase.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidationModuleBase} from '../FollowValidationModuleBase.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param collectLimit The maximum number of collects for this publication. + * @param currentCollects The current number of collects for this publication. + * @param amount The collecting cost associated with this publication. + * @param currency The currency associated with this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param endTimestamp The end timestamp after which collecting is impossible. + * @param followerOnly Whether only followers should be able to collect. + */ +struct ProfilePublicationData { + uint256 collectLimit; + uint256 currentCollects; + uint256 amount; + address currency; + address recipient; + uint16 referralFee; + bool followerOnly; + uint40 endTimestamp; +} + +/** + * @title LimitedTimedFeeCollectModule + * @author Lens Protocol + * + * @notice This is a simple Lens CollectModule implementation, inheriting from the ICollectModule interface and + * the FeeCollectModuleBase abstract contract. To optimize on gas, this module uses a constant 24 hour maximum + * collection time. + * + * This module works by allowing limited collects for a publication within the allotted time with a given fee. + */ +contract LimitedTimedFeeCollectModule is FeeModuleBase, FollowValidationModuleBase, ICollectModule { + using SafeERC20 for IERC20; + + uint24 internal constant ONE_DAY = 24 hours; + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor(address hub, address moduleGlobals) FeeModuleBase(moduleGlobals) ModuleBase(hub) {} + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * + * @param profileId The profile ID of the publication to initialize this module for's publishing profile. + * @param pubId The publication ID of the publication to initialize this module for. + * @param data The arbitrary data parameter, decoded into: + * uint256 collectLimit: The maximum amount of collects. + * uint256 amount: The currency total amount to levy. + * address currency: The currency address, must be internally whitelisted. + * address recipient: The custom recipient address to direct earnings to. + * uint16 referralFee: The referral fee to set. + * bool followerOnly: Whether only followers should be able to collect. + * + * @return bytes An abi encoded bytes parameter, containing (in order): collectLimit, amount, currency, recipient, referral fee & end timestamp. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + unchecked { + uint40 endTimestamp = uint40(block.timestamp) + ONE_DAY; + + ( + uint256 collectLimit, + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly + ) = abi.decode(data, (uint256, uint256, address, address, uint16, bool)); + if ( + collectLimit == 0 || + !_currencyWhitelisted(currency) || + recipient == address(0) || + referralFee > BPS_MAX || + amount == 0 + ) revert Errors.InitParamsInvalid(); + + _dataByPublicationByProfile[profileId][pubId].collectLimit = collectLimit; + _dataByPublicationByProfile[profileId][pubId].amount = amount; + _dataByPublicationByProfile[profileId][pubId].currency = currency; + _dataByPublicationByProfile[profileId][pubId].recipient = recipient; + _dataByPublicationByProfile[profileId][pubId].referralFee = referralFee; + _dataByPublicationByProfile[profileId][pubId].followerOnly = followerOnly; + _dataByPublicationByProfile[profileId][pubId].endTimestamp = endTimestamp; + + return + abi.encode( + collectLimit, + amount, + currency, + recipient, + referralFee, + followerOnly, + endTimestamp + ); + } + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower + * 2. Ensuring the current timestamp is less than or equal to the collect end timestamp + * 3. Ensuring the collect does not pass the collect limit + * 4. Charging a fee + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + uint256 endTimestamp = _dataByPublicationByProfile[profileId][pubId].endTimestamp; + if (block.timestamp > endTimestamp) revert Errors.CollectExpired(); + + if ( + _dataByPublicationByProfile[profileId][pubId].currentCollects >= + _dataByPublicationByProfile[profileId][pubId].collectLimit + ) { + revert Errors.MintLimitExceeded(); + } else { + ++_dataByPublicationByProfile[profileId][pubId].currentCollects; + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return ProfilepublicationData The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + returns (ProfilePublicationData memory) + { + return _dataByPublicationByProfile[profileId][pubId]; + } + + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = amount - treasuryAmount; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (amount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = amount - treasuryAmount; + + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } +} diff --git a/lens-protocol/core/contracts/core/modules/collect/PartialCarbonRetirementCollectModule.sol b/lens-protocol/core/contracts/core/modules/collect/PartialCarbonRetirementCollectModule.sol new file mode 100644 index 0000000..1dc6245 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/collect/PartialCarbonRetirementCollectModule.sol @@ -0,0 +1,466 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +import '@openzeppelin/contracts/utils/Strings.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +import {ICollectModule} from '../../../interfaces/ICollectModule.sol'; +import {Errors} from '../../../libraries/Errors.sol'; +import {FeeModuleBase} from '../../../core/modules/FeeModuleBase.sol'; +import {ModuleBase} from '../../../core/modules/ModuleBase.sol'; +import {FollowValidationModuleBase} from '../../../core/modules/FollowValidationModuleBase.sol'; + +import {CarbonRetireBase} from '../CarbonRetireBase.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * @param amount The collecting cost associated with this publication. 0 for free collect. + * @param currency The currency associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly Whether only followers should be able to collect. + * @param recipient The recipient address associated with this publication. + * @param endTimestamp The end timestamp after which collecting is impossible. + * @param currentCollects The current number of collects for this publication. + * @param collectLimit The maximum number of collects for this publication (0 for unlimited) + * @param poolToken The carbon token to be used for carbon retirement. + * @param retirementSplit Fraction (BPS) of amount that goes into carbon retirement. + */ +struct ProfilePublicationData { + uint160 amount; + address currency; + uint16 referralFee; + bool followerOnly; + address recipient; + uint40 endTimestamp; + uint64 currentCollects; + uint64 collectLimit; + address poolToken; + uint16 retirementSplit; +} + +/** + * @notice A struct containing the necessary data to initialize Stepwise Collect Module. + * @param amount The collecting cost associated with this publication. 0 for free collect. + * @param collectLimit The maximum number of collects for this publication (0 for unlimited) + * @param currency The currency associated with this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly Whether only followers should be able to collect. + * @param endTimestamp The end timestamp after which collecting is impossible. + * @param poolToken The carbon token to be used for carbon retirement. + * @param retirementSplit Fraction (BPS) of amount that goes into carbon retirement. + */ +struct PartialCarbonRetirementCollectModuleInitData { + uint160 amount; + uint64 collectLimit; + address currency; + address recipient; + uint16 referralFee; + bool followerOnly; + uint40 endTimestamp; + address poolToken; + uint16 retirementSplit; +} + +/** + * @title PartialCarbonRetirementCollectModule + * @author Lens Protocol + * + * @notice This module sends a chosen fraction of the collect fee to perform carbon retirement. + * The Publisher can choose the carbon pool token and the fraction of the total collect fee for the retirement. + * The collector only needs to hold the collect fee currency, no carbon tokens. Swap happens through the retirement aggregator during collect. + * + * Treasury fee and referralFee are calculated only on the amount that the publisher/recipient gets, ignoring the retirement amount. + * + * If retirement is not possible during collect, the collect process still takes place. + * In this case, the recipient/publisher gets the full amount and a notice in the transaction that they should perform the retirement manually at a later point. + * In this case, treasury fee and referralFee are calculated on the total amount that the recipient/publisher gets. + * + */ +contract PartialCarbonRetirementCollectModule is + CarbonRetireBase, + FeeModuleBase, + FollowValidationModuleBase, + ICollectModule +{ + using SafeERC20 for IERC20; + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor( + address hub, + address moduleGlobals, + address klimaInfinity + ) FeeModuleBase(moduleGlobals) ModuleBase(hub) CarbonRetireBase(klimaInfinity) {} + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * @param data The arbitrary data parameter, decoded into: + * recipientAmount: The collecting cost associated with this publication. 0 for free collect. + * collectLimit: The maximum number of collects for this publication. 0 for no limit. + * currency: The currency associated with this publication. + * referralFee: The referral fee associated with this publication. + * followerOnly: True if only followers of publisher may collect the post. + * endTimestamp: The end timestamp after which collecting is impossible. 0 for no expiry. + * recipient: Recipient of collect fees. + * pooltToken: Carbon token for retierement + * retirementSplit: Fration of amount to go to retirement + * + * @return An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external virtual onlyHub returns (bytes memory) { + PartialCarbonRetirementCollectModuleInitData memory initData = abi.decode( + data, + (PartialCarbonRetirementCollectModuleInitData) + ); + { + uint256 retirementAmount = (initData.retirementSplit * initData.amount) / BPS_MAX; + if ( + !checkRetirementSwapFeasibility( + initData.currency, + initData.poolToken, + retirementAmount + ) || + !_currencyWhitelisted(initData.currency) || + // TODO: should this be included? Removed, because 100% retirement doesn't need recipient + //initData.recipient == address(0) || + initData.referralFee > BPS_MAX || + initData.retirementSplit > BPS_MAX || + (initData.endTimestamp != 0 && initData.endTimestamp < block.timestamp) + ) revert Errors.InitParamsInvalid(); + } + + _dataByPublicationByProfile[profileId][pubId] = ProfilePublicationData({ + amount: initData.amount, + currency: initData.currency, + referralFee: initData.referralFee, + followerOnly: initData.followerOnly, + recipient: initData.recipient, + endTimestamp: initData.endTimestamp, + currentCollects: 0, + collectLimit: initData.collectLimit, + poolToken: initData.poolToken, + retirementSplit: initData.retirementSplit + }); + return data; + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower + * 2. Ensuring the current timestamp is less than or equal to the collect end timestamp + * 3. Ensuring the collect does not pass the collect limit + * 4. Charging a fee + * 5. Performing the retirement and collect + * + * @inheritdoc ICollectModule + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + uint256 endTimestamp = _dataByPublicationByProfile[profileId][pubId].endTimestamp; + if (endTimestamp != 0 && block.timestamp > endTimestamp) revert Errors.CollectExpired(); + + if ( + _dataByPublicationByProfile[profileId][pubId].collectLimit != 0 && + _dataByPublicationByProfile[profileId][pubId].currentCollects >= + _dataByPublicationByProfile[profileId][pubId].collectLimit + ) { + revert Errors.MintLimitExceeded(); + } else { + unchecked { + ++_dataByPublicationByProfile[profileId][pubId].currentCollects; + } + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + } + + /** + * @dev Internal processing of a collect: + * 1. Calculation of fees + * 2. Validation that fees are what collector expected + * 3. Transfer of fees to recipient and treasury + * + * @param collector The address that will collect the post. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Arbitrary data __passed from the collector!__ to be decoded. + */ + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal virtual { + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + uint256 retirementAmount = (_dataByPublicationByProfile[profileId][pubId].retirementSplit * + _dataByPublicationByProfile[profileId][pubId].amount) / BPS_MAX; + + // TODO: Learn what this does. Guess: checks that calldata of collect equals init data of publication + _validateDataIsExpected( + data, + currency, + _dataByPublicationByProfile[profileId][pubId].amount + ); + + // Try retirement and return recipientAmount. + uint256 recipientAmount = _performCarbonRetirement( + collector, + _dataByPublicationByProfile[profileId][pubId].recipient, + pubId, + profileId, + currency, + _dataByPublicationByProfile[profileId][pubId].poolToken, + retirementAmount + ); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + uint256 treasuryAmount = (recipientAmount * treasuryFee) / BPS_MAX; + + // Send amount after treasury cut, to all recipients + _transferToRecipients( + currency, + collector, + profileId, + pubId, + recipientAmount - treasuryAmount + ); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @dev Internal processing of a collect: + * 1. Calculation of fees + * 2. Validation that fees are what collector expected + * 3. Transfer of fees to recipient(-s) and treasury + * + * @param collector The address that will collect the post. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Arbitrary data __passed from the collector!__ to be decoded. + */ + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal virtual { + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + uint256 retirementAmount = (_dataByPublicationByProfile[profileId][pubId].retirementSplit * + _dataByPublicationByProfile[profileId][pubId].amount) / BPS_MAX; + + // TODO: Learn what this does. Guess: checks that calldata of collect equals init data of publication + _validateDataIsExpected( + data, + currency, + _dataByPublicationByProfile[profileId][pubId].amount + ); + + // Try retirement and return recipientAmount. + uint256 recipientAmount = _performCarbonRetirement( + collector, + _dataByPublicationByProfile[profileId][pubId].recipient, + pubId, + profileId, + currency, + _dataByPublicationByProfile[profileId][pubId].poolToken, + retirementAmount + ); + + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (recipientAmount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = recipientAmount - treasuryAmount; + adjustedAmount = _transferToReferrals( + currency, + referrerProfileId, + collector, + profileId, + pubId, + adjustedAmount + ); + + _transferToRecipients(currency, collector, profileId, pubId, adjustedAmount); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @dev Wrapper for carbon retirement: + * Creates retirement messages + * Performs (attempts) retirement + * Returns remaining recipient amount + * + * @param collector The address that will collect the post. + * @param recipient The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param profileId Arbitrary data __passed from the collector!__ to be decoded. + * @param currency Currency of the collect + * @param poolToken Carbon pool token for retirement + * @param retirementAmount Amount of currency to be retired + */ + function _performCarbonRetirement( + address collector, + address recipient, + uint256 pubId, + uint256 profileId, + address currency, + address poolToken, + uint256 retirementAmount + ) internal returns (uint256 recipientAmount) { + // Perform retirement if checkSwapFeasibility works. + if (checkRetirementSwapFeasibility(currency, poolToken, retirementAmount)) { + string memory retiringEntityString = string( + abi.encodePacked( + 'Collecting Lens profile: ', + Strings.toString(profileId), + ', by collector:', + Strings.toHexString(uint256(uint160(collector)), 20) + //Strings.toHexString(collector) + ) + ); + string memory beneficiaryString = string( + abi.encodePacked( + 'Lens publication: ', + Strings.toString(pubId), + ', by publisher: ', + Strings.toHexString(uint256(uint160(recipient)), 20) + //Strings.toHexString(recipient) + ) + ); + string memory retirementMessage = string( + abi.encodePacked( + 'Lens Protocol carbon retirement for collect of publication: ', + Strings.toString(pubId) + ) + ); + _retireCarbon( + collector, + recipient, + currency, + poolToken, + retirementAmount, + retiringEntityString, + beneficiaryString, + retirementMessage + ); + + recipientAmount = + _dataByPublicationByProfile[profileId][pubId].amount - + retirementAmount; + } else { + // TODO: Up to debate. This fallback sends everything to recipient with treasury fee for everything. + recipientAmount = _dataByPublicationByProfile[profileId][pubId].amount; + // TODO: Add event or something to signal to recipient that they should perform + // a manual retirement of all failed retirements at a later time + } + } + + /** + * @dev Transfers the fee to recipient + * + * Override this to add additional functionality (e.g. multiple recipients) + * + * @param currency Currency of the transaction + * @param collector The address that collects the post (and pays the fee). + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param amount Amount to transfer to recipient(-s) + */ + function _transferToRecipients( + address currency, + address collector, + uint256 profileId, + uint256 pubId, + uint256 amount + ) internal virtual { + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + if (amount > 0) { + IERC20(currency).safeTransferFrom(collector, recipient, amount); + } + } + + /** + * @dev Transfers the part of fee to referral(-s) + * + * Override this to add additional functionality (e.g. multiple referrals) + * + * @param currency Currency of the transaction + * @param referrerProfileId The address of the referral. + * @param collector The address that collects the post (and pays the fee). + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param adjustedAmount Amount of the fee after subtracting the Treasury part. + */ + function _transferToReferrals( + address currency, + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + uint256 adjustedAmount + ) internal virtual returns (uint256) { + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + if (referralAmount > 0) { + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + // Send referral fee in normal ERC20 tokens + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + } + return adjustedAmount; + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData( + uint256 profileId, + uint256 pubId + ) external view virtual returns (ProfilePublicationData memory) { + return _dataByPublicationByProfile[profileId][pubId]; + } +} diff --git a/lens-protocol/core/contracts/core/modules/collect/RevertCollectModule.sol b/lens-protocol/core/contracts/core/modules/collect/RevertCollectModule.sol new file mode 100644 index 0000000..5995e11 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/collect/RevertCollectModule.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ICollectModule} from '../../../interfaces/ICollectModule.sol'; +import {Errors} from '../../../libraries/Errors.sol'; + +/** + * @title RevertCollectModule + * @author Lens Protocol + * + * @notice This is a simple Lens CollectModule implementation, inheriting from the ICollectModule interface. + * + * This module works by disallowing all collects. + */ +contract RevertCollectModule is ICollectModule { + /** + * @dev There is nothing needed at initialization. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external pure override returns (bytes memory) { + return new bytes(0); + } + + /** + * @dev Processes a collect by: + * 1. Always reverting + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external pure override { + revert Errors.CollectNotAllowed(); + } +} diff --git a/lens-protocol/core/contracts/core/modules/collect/TimedFeeCollectModule.sol b/lens-protocol/core/contracts/core/modules/collect/TimedFeeCollectModule.sol new file mode 100644 index 0000000..3674d5b --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/collect/TimedFeeCollectModule.sol @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ICollectModule} from '../../../interfaces/ICollectModule.sol'; +import {IFollowModule} from '../../../interfaces/IFollowModule.sol'; +import {ILensHub} from '../../../interfaces/ILensHub.sol'; +import {Errors} from '../../../libraries/Errors.sol'; +import {FeeModuleBase} from '../FeeModuleBase.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidationModuleBase} from '../FollowValidationModuleBase.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param amount The collecting cost associated with this publication. + * @param currency The currency associated with this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param endTimestamp The end timestamp after which collecting is impossible. + * @param followerOnly Whether only followers should be able to collect. + */ +struct ProfilePublicationData { + uint256 amount; + address currency; + address recipient; + uint16 referralFee; + bool followerOnly; + uint40 endTimestamp; +} + +/** + * @title TimedFeeCollectModule + * @author Lens Protocol + * + * @notice This is a simple Lens CollectModule implementation, inheriting from the ICollectModule interface and + * the FeeCollectModuleBase abstract contract. To optimize on gas, this module uses a constant 24 hour maximum + * collection time. + * + * This module works by allowing unlimited collects for a publication within the allotted time with a given fee. + * + * NOTE: If data passed on initialization is empty, this module will only check for the time limit. + */ +contract TimedFeeCollectModule is FeeModuleBase, FollowValidationModuleBase, ICollectModule { + using SafeERC20 for IERC20; + + uint24 internal constant ONE_DAY = 24 hours; + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor(address hub, address moduleGlobals) FeeModuleBase(moduleGlobals) ModuleBase(hub) {} + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * + * @param profileId The profile ID of the publication to initialize this module for's publishing profile. + * @param pubId The publication ID of the publication to initialize this module for. + * @param data The arbitrary data parameter, decoded into: + * uint256 amount: The currency total amount to levy. + * address currency: The currency address, must be internally whitelisted. + * address recipient: The custom recipient address to direct earnings to. + * uint16 referralFee: The referral fee to set. + * bool followerOnly: Whether only followers should be able to collect. + * + * @return bytes An abi encoded bytes parameter, containing (in order): amount, currency, recipient, referral fee & end timestamp. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + unchecked { + uint40 endTimestamp = uint40(block.timestamp) + ONE_DAY; + + ( + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly + ) = abi.decode(data, (uint256, address, address, uint16, bool)); + if ( + !_currencyWhitelisted(currency) || + recipient == address(0) || + referralFee > BPS_MAX || + amount == 0 + ) revert Errors.InitParamsInvalid(); + + _dataByPublicationByProfile[profileId][pubId].amount = amount; + _dataByPublicationByProfile[profileId][pubId].currency = currency; + _dataByPublicationByProfile[profileId][pubId].recipient = recipient; + _dataByPublicationByProfile[profileId][pubId].referralFee = referralFee; + _dataByPublicationByProfile[profileId][pubId].followerOnly = followerOnly; + _dataByPublicationByProfile[profileId][pubId].endTimestamp = endTimestamp; + + return abi.encode(amount, currency, recipient, referralFee, followerOnly, endTimestamp); + } + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower + * 2. Ensuring the current timestamp is less than or equal to the collect end timestamp + * 3. Charging a fee + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + uint256 endTimestamp = _dataByPublicationByProfile[profileId][pubId].endTimestamp; + if (block.timestamp > endTimestamp) revert Errors.CollectExpired(); + + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return ProfilePublicationData The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + returns (ProfilePublicationData memory) + { + return _dataByPublicationByProfile[profileId][pubId]; + } + + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = amount - treasuryAmount; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (amount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = amount - treasuryAmount; + + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } +} diff --git a/lens-protocol/core/contracts/core/modules/follow/ApprovalFollowModule.sol b/lens-protocol/core/contracts/core/modules/follow/ApprovalFollowModule.sol new file mode 100644 index 0000000..cab93e2 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/follow/ApprovalFollowModule.sol @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IFollowModule} from '../../../interfaces/IFollowModule.sol'; +import {Errors} from '../../../libraries/Errors.sol'; +import {Events} from '../../../libraries/Events.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidatorFollowModuleBase} from './FollowValidatorFollowModuleBase.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @title ApprovalFollowModule + * @author Lens Protocol + * + * @notice This follow module only allows addresses that are approved for a profile by the profile owner to follow. + */ +contract ApprovalFollowModule is FollowValidatorFollowModuleBase { + // We use a triple nested mapping so that, on profile transfer, the previous approved address list is invalid; + mapping(address => mapping(uint256 => mapping(address => bool))) + internal _approvedByProfileByOwner; + + constructor(address hub) ModuleBase(hub) {} + + /** + * @notice A custom function that allows profile owners to customize approved addresses. + * + * @param profileId The profile ID to approve/disapprove follower addresses for. + * @param addresses The addresses to approve/disapprove for following the profile. + * @param toApprove Whether to approve or disapprove the addresses for following the profile. + */ + function approve( + uint256 profileId, + address[] calldata addresses, + bool[] calldata toApprove + ) external { + if (addresses.length != toApprove.length) revert Errors.InitParamsInvalid(); + address owner = IERC721(HUB).ownerOf(profileId); + if (msg.sender != owner) revert Errors.NotProfileOwner(); + + uint256 addressesLength = addresses.length; + for (uint256 i = 0; i < addressesLength; ) { + _approvedByProfileByOwner[owner][profileId][addresses[i]] = toApprove[i]; + unchecked { + ++i; + } + } + + emit Events.FollowsApproved(owner, profileId, addresses, toApprove, block.timestamp); + } + + /** + * @notice This follow module works on custom profile owner approvals. + * + * @param profileId The profile ID of the profile to initialize this module for. + * @param data The arbitrary data parameter, decoded into: + * address[] addresses: The array of addresses to approve initially. + * + * @return bytes An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializeFollowModule(uint256 profileId, bytes calldata data) + external + override + onlyHub + returns (bytes memory) + { + address owner = IERC721(HUB).ownerOf(profileId); + + if (data.length > 0) { + address[] memory addresses = abi.decode(data, (address[])); + uint256 addressesLength = addresses.length; + for (uint256 i = 0; i < addressesLength; ) { + _approvedByProfileByOwner[owner][profileId][addresses[i]] = true; + unchecked { + ++i; + } + } + } + return data; + } + + /** + * @dev Processes a follow by: + * 1. Validating that the follower has been approved for that profile by the profile owner + */ + function processFollow( + address follower, + uint256 profileId, + bytes calldata data + ) external override onlyHub { + address owner = IERC721(HUB).ownerOf(profileId); + if (!_approvedByProfileByOwner[owner][profileId][follower]) + revert Errors.FollowNotApproved(); + _approvedByProfileByOwner[owner][profileId][follower] = false; // prevents repeat follows + } + + /** + * @dev We don't need to execute any additional logic on transfers in this follow module. + */ + function followModuleTransferHook( + uint256 profileId, + address from, + address to, + uint256 followNFTTokenId + ) external override {} + + /** + * @notice Returns whether the given address is approved for the profile owned by a given address. + * + * @param profileOwner The profile owner of the profile to query the approval with. + * @param profileId The token ID of the profile to query approval with. + * @param toCheck The address to query approval for. + * + * @return bool True if the address is approved and false otherwise. + */ + function isApproved( + address profileOwner, + uint256 profileId, + address toCheck + ) external view returns (bool) { + return _approvedByProfileByOwner[profileOwner][profileId][toCheck]; + } + + /** + * @notice Returns whether the given addresses are approved for the profile owned by a given address. + * + * @param profileOwner The profile owner of the profile to query the approvals with. + * @param profileId The token ID of the profile to query approvals with. + * @param toCheck The address array to query approvals for. + * + * @return bool[] true if the address at the specified index is approved and false otherwise. + */ + function isApprovedArray( + address profileOwner, + uint256 profileId, + address[] calldata toCheck + ) external view returns (bool[] memory) { + bool[] memory approved = new bool[](toCheck.length); + uint256 toCheckLength = toCheck.length; + for (uint256 i = 0; i < toCheckLength; ) { + approved[i] = _approvedByProfileByOwner[profileOwner][profileId][toCheck[i]]; + unchecked { + ++i; + } + } + return approved; + } +} diff --git a/lens-protocol/core/contracts/core/modules/follow/FeeFollowModule.sol b/lens-protocol/core/contracts/core/modules/follow/FeeFollowModule.sol new file mode 100644 index 0000000..4bb479b --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/follow/FeeFollowModule.sol @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IFollowModule} from '../../../interfaces/IFollowModule.sol'; +import {ILensHub} from '../../../interfaces/ILensHub.sol'; +import {Errors} from '../../../libraries/Errors.sol'; +import {FeeModuleBase} from '../FeeModuleBase.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidatorFollowModuleBase} from './FollowValidatorFollowModuleBase.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @notice A struct containing the necessary data to execute follow actions on a given profile. + * + * @param currency The currency associated with this profile. + * @param amount The following cost associated with this profile. + * @param recipient The recipient address associated with this profile. + */ +struct ProfileData { + address currency; + uint256 amount; + address recipient; +} + +/** + * @title FeeFollowModule + * @author Lens Protocol + * + * @notice This is a simple Lens FollowModule implementation, inheriting from the IFollowModule interface, but with additional + * variables that can be controlled by governance, such as the governance & treasury addresses as well as the treasury fee. + */ +contract FeeFollowModule is FeeModuleBase, FollowValidatorFollowModuleBase { + using SafeERC20 for IERC20; + + mapping(uint256 => ProfileData) internal _dataByProfile; + + constructor(address hub, address moduleGlobals) FeeModuleBase(moduleGlobals) ModuleBase(hub) {} + + /** + * @notice This follow module levies a fee on follows. + * + * @param profileId The profile ID of the profile to initialize this module for. + * @param data The arbitrary data parameter, decoded into: + * address currency: The currency address, must be internally whitelisted. + * uint256 amount: The currency total amount to levy. + * address recipient: The custom recipient address to direct earnings to. + * + * @return bytes An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializeFollowModule(uint256 profileId, bytes calldata data) + external + override + onlyHub + returns (bytes memory) + { + (uint256 amount, address currency, address recipient) = abi.decode( + data, + (uint256, address, address) + ); + if (!_currencyWhitelisted(currency) || recipient == address(0) || amount == 0) + revert Errors.InitParamsInvalid(); + + _dataByProfile[profileId].amount = amount; + _dataByProfile[profileId].currency = currency; + _dataByProfile[profileId].recipient = recipient; + return data; + } + + /** + * @dev Processes a follow by: + * 1. Charging a fee + */ + function processFollow( + address follower, + uint256 profileId, + bytes calldata data + ) external override onlyHub { + uint256 amount = _dataByProfile[profileId].amount; + address currency = _dataByProfile[profileId].currency; + _validateDataIsExpected(data, currency, amount); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + address recipient = _dataByProfile[profileId].recipient; + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = amount - treasuryAmount; + + IERC20(currency).safeTransferFrom(follower, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(follower, treasury, treasuryAmount); + } + + /** + * @dev We don't need to execute any additional logic on transfers in this follow module. + */ + function followModuleTransferHook( + uint256 profileId, + address from, + address to, + uint256 followNFTTokenId + ) external override {} + + /** + * @notice Returns the profile data for a given profile, or an empty struct if that profile was not initialized + * with this module. + * + * @param profileId The token ID of the profile to query. + * + * @return ProfileData The ProfileData struct mapped to that profile. + */ + function getProfileData(uint256 profileId) external view returns (ProfileData memory) { + return _dataByProfile[profileId]; + } +} diff --git a/lens-protocol/core/contracts/core/modules/follow/FollowValidatorFollowModuleBase.sol b/lens-protocol/core/contracts/core/modules/follow/FollowValidatorFollowModuleBase.sol new file mode 100644 index 0000000..c0e1ed8 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/follow/FollowValidatorFollowModuleBase.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IFollowModule} from '../../../interfaces/IFollowModule.sol'; +import {ILensHub} from '../../../interfaces/ILensHub.sol'; +import {Errors} from '../../../libraries/Errors.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @title FollowValidatorFollowModuleBase + * @author Lens Protocol + * + * @notice This abstract contract adds the default expected behavior for follow validation in a follow module + * to inheriting contracts. + */ +abstract contract FollowValidatorFollowModuleBase is ModuleBase, IFollowModule { + /** + * @notice Standard function to validate follow NFT ownership. This module is agnostic to follow NFT token IDs + * and other properties. + */ + function isFollowing( + uint256 profileId, + address follower, + uint256 followNFTTokenId + ) external view override returns (bool) { + address followNFT = ILensHub(HUB).getFollowNFT(profileId); + if (followNFT == address(0)) { + return false; + } else { + return + followNFTTokenId == 0 + ? IERC721(followNFT).balanceOf(follower) != 0 + : IERC721(followNFT).ownerOf(followNFTTokenId) == follower; + } + } +} diff --git a/lens-protocol/core/contracts/core/modules/follow/ProfileFollowModule.sol b/lens-protocol/core/contracts/core/modules/follow/ProfileFollowModule.sol new file mode 100644 index 0000000..2afe6e4 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/follow/ProfileFollowModule.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IFollowModule} from '../../../interfaces/IFollowModule.sol'; +import {Errors} from '../../../libraries/Errors.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidatorFollowModuleBase} from './FollowValidatorFollowModuleBase.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @title ProfileFollowModule + * @author Lens Protocol + * + * @notice A Lens Profile NFT token-gated follow module with single follow per token validation. + */ +contract ProfileFollowModule is FollowValidatorFollowModuleBase { + /** + * Given two profile IDs tells if the former has already been used to follow the latter. + */ + mapping(uint256 => mapping(uint256 => bool)) public isProfileFollowing; + + constructor(address hub) ModuleBase(hub) {} + + /** + * @notice This follow module works on custom profile owner approvals. + * + * @param profileId The profile ID of the profile to initialize this module for. + * @param data The arbitrary data parameter, which in this particular module initialization will be just ignored. + * + * @return bytes Empty bytes. + */ + function initializeFollowModule(uint256 profileId, bytes calldata data) + external + override + onlyHub + returns (bytes memory) + { + return new bytes(0); + } + + /** + * @dev Processes a follow by: + * 1. Validating that the follower owns the profile passed through the data param. + * 2. Validating that the profile that is being used to execute the follow was not already used for following the + * given profile. + */ + function processFollow( + address follower, + uint256 profileId, + bytes calldata data + ) external override onlyHub { + uint256 followerProfileId = abi.decode(data, (uint256)); + if (IERC721(HUB).ownerOf(followerProfileId) != follower) { + revert Errors.NotProfileOwner(); + } + if (isProfileFollowing[followerProfileId][profileId]) { + revert Errors.FollowInvalid(); + } else { + isProfileFollowing[followerProfileId][profileId] = true; + } + } + + /** + * @dev We don't need to execute any additional logic on transfers in this follow module. + */ + function followModuleTransferHook( + uint256 profileId, + address from, + address to, + uint256 followNFTTokenId + ) external override {} +} diff --git a/lens-protocol/core/contracts/core/modules/follow/RevertFollowModule.sol b/lens-protocol/core/contracts/core/modules/follow/RevertFollowModule.sol new file mode 100644 index 0000000..6695583 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/follow/RevertFollowModule.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Errors} from '../../../libraries/Errors.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidatorFollowModuleBase} from './FollowValidatorFollowModuleBase.sol'; + +/** + * @title RevertFollowModule + * @author Lens Protocol + * + * @notice This follow module rejects all follow attempts. + */ +contract RevertFollowModule is FollowValidatorFollowModuleBase { + constructor(address hub) ModuleBase(hub) {} + + /** + * @notice This follow module works on custom profile owner approvals. + * + * @param profileId The profile ID of the profile to initialize this module for. + * @param data The arbitrary data parameter, which in this particular module initialization will be just ignored. + * + * @return bytes Empty bytes. + */ + function initializeFollowModule(uint256 profileId, bytes calldata data) + external + view + override + onlyHub + returns (bytes memory) + { + return new bytes(0); + } + + /** + * @dev Processes a follow by rejecting it reverting the transaction. + */ + function processFollow( + address follower, + uint256 profileId, + bytes calldata data + ) external view override onlyHub { + revert Errors.FollowInvalid(); + } + + /** + * @dev We don't need to execute any additional logic on transfers in this follow module. + */ + function followModuleTransferHook( + uint256 profileId, + address from, + address to, + uint256 followNFTTokenId + ) external override {} +} diff --git a/lens-protocol/core/contracts/core/modules/reference/FollowerOnlyReferenceModule.sol b/lens-protocol/core/contracts/core/modules/reference/FollowerOnlyReferenceModule.sol new file mode 100644 index 0000000..9effa04 --- /dev/null +++ b/lens-protocol/core/contracts/core/modules/reference/FollowerOnlyReferenceModule.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IReferenceModule} from '../../../interfaces/IReferenceModule.sol'; +import {ModuleBase} from '../ModuleBase.sol'; +import {FollowValidationModuleBase} from '../FollowValidationModuleBase.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @title FollowerOnlyReferenceModule + * @author Lens Protocol + * + * @notice A simple reference module that validates that comments or mirrors originate from a profile owned + * by a follower. + */ +contract FollowerOnlyReferenceModule is FollowValidationModuleBase, IReferenceModule { + constructor(address hub) ModuleBase(hub) {} + + /** + * @dev There is nothing needed at initialization. + */ + function initializeReferenceModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external pure override returns (bytes memory) { + return new bytes(0); + } + + /** + * @notice Validates that the commenting profile's owner is a follower. + * + * NOTE: We don't need to care what the pointed publication is in this context. + */ + function processComment( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external view override { + address commentCreator = IERC721(HUB).ownerOf(profileId); + _checkFollowValidity(profileIdPointed, commentCreator); + } + + /** + * @notice Validates that the commenting profile's owner is a follower. + * + * NOTE: We don't need to care what the pointed publication is in this context. + */ + function processMirror( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external view override { + address mirrorCreator = IERC721(HUB).ownerOf(profileId); + _checkFollowValidity(profileIdPointed, mirrorCreator); + } +} diff --git a/lens-protocol/core/contracts/core/storage/LensHubStorage.sol b/lens-protocol/core/contracts/core/storage/LensHubStorage.sol new file mode 100644 index 0000000..980c123 --- /dev/null +++ b/lens-protocol/core/contracts/core/storage/LensHubStorage.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {DataTypes} from '../../libraries/DataTypes.sol'; + +/** + * @title LensHubStorage + * @author Lens Protocol + * + * @notice This is an abstract contract that *only* contains storage for the LensHub contract. This + * *must* be inherited last (bar interfaces) in order to preserve the LensHub storage layout. Adding + * storage variables should be done solely at the bottom of this contract. + */ +abstract contract LensHubStorage { + bytes32 internal constant SET_DEFAULT_PROFILE_WITH_SIG_TYPEHASH = + keccak256( + 'SetDefaultProfileWithSig(address wallet,uint256 profileId,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant SET_FOLLOW_MODULE_WITH_SIG_TYPEHASH = + keccak256( + 'SetFollowModuleWithSig(uint256 profileId,address followModule,bytes followModuleInitData,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant SET_FOLLOW_NFT_URI_WITH_SIG_TYPEHASH = + keccak256( + 'SetFollowNFTURIWithSig(uint256 profileId,string followNFTURI,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant SET_DISPATCHER_WITH_SIG_TYPEHASH = + keccak256( + 'SetDispatcherWithSig(uint256 profileId,address dispatcher,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant SET_PROFILE_IMAGE_URI_WITH_SIG_TYPEHASH = + keccak256( + 'SetProfileImageURIWithSig(uint256 profileId,string imageURI,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant POST_WITH_SIG_TYPEHASH = + keccak256( + 'PostWithSig(uint256 profileId,string contentURI,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant COMMENT_WITH_SIG_TYPEHASH = + keccak256( + 'CommentWithSig(uint256 profileId,string contentURI,uint256 profileIdPointed,uint256 pubIdPointed,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant MIRROR_WITH_SIG_TYPEHASH = + keccak256( + 'MirrorWithSig(uint256 profileId,uint256 profileIdPointed,uint256 pubIdPointed,bytes referenceModuleData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant FOLLOW_WITH_SIG_TYPEHASH = + keccak256( + 'FollowWithSig(uint256[] profileIds,bytes[] datas,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant COLLECT_WITH_SIG_TYPEHASH = + keccak256( + 'CollectWithSig(uint256 profileId,uint256 pubId,bytes data,uint256 nonce,uint256 deadline)' + ); + + mapping(address => bool) internal _profileCreatorWhitelisted; + mapping(address => bool) internal _followModuleWhitelisted; + mapping(address => bool) internal _collectModuleWhitelisted; + mapping(address => bool) internal _referenceModuleWhitelisted; + + mapping(uint256 => address) internal _dispatcherByProfile; + mapping(bytes32 => uint256) internal _profileIdByHandleHash; + mapping(uint256 => DataTypes.ProfileStruct) internal _profileById; + mapping(uint256 => mapping(uint256 => DataTypes.PublicationStruct)) internal _pubByIdByProfile; + + mapping(address => uint256) internal _defaultProfileByAddress; + + uint256 internal _profileCounter; + address internal _governance; + address internal _emergencyAdmin; +} diff --git a/lens-protocol/core/contracts/interfaces/ICollectModule.sol b/lens-protocol/core/contracts/interfaces/ICollectModule.sol new file mode 100644 index 0000000..f490942 --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/ICollectModule.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +/** + * @title ICollectModule + * @author Lens Protocol + * + * @notice This is the standard interface for all Lens-compatible CollectModules. + */ +interface ICollectModule { + /** + * @notice Initializes data for a given publication being published. This can only be called by the hub. + * + * @param profileId The token ID of the profile publishing the publication. + * @param pubId The associated publication's LensHub publication ID. + * @param data Arbitrary data __passed from the user!__ to be decoded. + * + * @return bytes An abi encoded byte array encapsulating the execution's state changes. This will be emitted by the + * hub alongside the collect module's address and should be consumed by front ends. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external returns (bytes memory); + + /** + * @notice Processes a collect action for a given publication, this can only be called by the hub. + * + * @param referrerProfileId The LensHub profile token ID of the referrer's profile (only different in case of mirrors). + * @param collector The collector address. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Arbitrary data __passed from the collector!__ to be decoded. + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external; +} diff --git a/lens-protocol/core/contracts/interfaces/ICollectNFT.sol b/lens-protocol/core/contracts/interfaces/ICollectNFT.sol new file mode 100644 index 0000000..1f37ded --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/ICollectNFT.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +/** + * @title ICollectNFT + * @author Lens Protocol + * + * @notice This is the interface for the CollectNFT contract. Which is cloned upon the first collect for any given + * publication. + */ +interface ICollectNFT { + /** + * @notice Initializes the collect NFT, setting the feed as the privileged minter, storing the collected publication pointer + * and initializing the name and symbol in the LensNFTBase contract. + * + * @param profileId The token ID of the profile in the hub that this collectNFT points to. + * @param pubId The profile publication ID in the hub that this collectNFT points to. + * @param name The name to set for this NFT. + * @param symbol The symbol to set for this NFT. + */ + function initialize( + uint256 profileId, + uint256 pubId, + string calldata name, + string calldata symbol + ) external; + + /** + * @notice Mints a collect NFT to the specified address. This can only be called by the hub, and is called + * upon collection. + * + * @param to The address to mint the NFT to. + * + * @return uint256 An interger representing the minted token ID. + */ + function mint(address to) external returns (uint256); + + /** + * @notice Returns the source publication pointer mapped to this collect NFT. + * + * @return tuple First the profile ID uint256, and second the pubId uint256. + */ + function getSourcePublicationPointer() external view returns (uint256, uint256); +} diff --git a/lens-protocol/core/contracts/interfaces/IERC20Burnable.sol b/lens-protocol/core/contracts/interfaces/IERC20Burnable.sol new file mode 100644 index 0000000..ac410ca --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/IERC20Burnable.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) + +pragma solidity 0.8.10; + +/** + * @dev Extension of the ERC20 standard to support burning. + */ +interface IERC20Burnable { + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `from` to `to` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address from, + address to, + uint256 amount + ) external returns (bool); + + /** + * @dev Destroys `amount` tokens from the caller. + * + * See {ERC20-_burn}. + */ + function burn(uint256 amount) external; + + /** + * @dev Destroys `amount` tokens from `account`, deducting from the caller's + * allowance. + * + * See {ERC20-_burn} and {ERC20-allowance}. + * + * Requirements: + * + * - the caller must have allowance for ``accounts``'s tokens of at least + * `amount`. + */ + function burnFrom(address account, uint256 amount) external; + + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} diff --git a/lens-protocol/core/contracts/interfaces/IFollowModule.sol b/lens-protocol/core/contracts/interfaces/IFollowModule.sol new file mode 100644 index 0000000..c6f636c --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/IFollowModule.sol @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +/** + * @title IFollowModule + * @author Lens Protocol + * + * @notice This is the standard interface for all Lens-compatible FollowModules. + */ +interface IFollowModule { + /** + * @notice Initializes a follow module for a given Lens profile. This can only be called by the hub contract. + * + * @param profileId The token ID of the profile to initialize this follow module for. + * @param data Arbitrary data passed by the profile creator. + * + * @return bytes The encoded data to emit in the hub. + */ + function initializeFollowModule(uint256 profileId, bytes calldata data) + external + returns (bytes memory); + + /** + * @notice Processes a given follow, this can only be called from the LensHub contract. + * + * @param follower The follower address. + * @param profileId The token ID of the profile being followed. + * @param data Arbitrary data passed by the follower. + */ + function processFollow( + address follower, + uint256 profileId, + bytes calldata data + ) external; + + /** + * @notice This is a transfer hook that is called upon follow NFT transfer in `beforeTokenTransfer. This can + * only be called from the LensHub contract. + * + * NOTE: Special care needs to be taken here: It is possible that follow NFTs were issued before this module + * was initialized if the profile's follow module was previously different. This transfer hook should take this + * into consideration, especially when the module holds state associated with individual follow NFTs. + * + * @param profileId The token ID of the profile associated with the follow NFT being transferred. + * @param from The address sending the follow NFT. + * @param to The address receiving the follow NFT. + * @param followNFTTokenId The token ID of the follow NFT being transferred. + */ + function followModuleTransferHook( + uint256 profileId, + address from, + address to, + uint256 followNFTTokenId + ) external; + + /** + * @notice This is a helper function that could be used in conjunction with specific collect modules. + * + * NOTE: This function IS meant to replace a check on follower NFT ownership. + * + * NOTE: It is assumed that not all collect modules are aware of the token ID to pass. In these cases, + * this should receive a `followNFTTokenId` of 0, which is impossible regardless. + * + * One example of a use case for this would be a subscription-based following system: + * 1. The collect module: + * - Decodes a follower NFT token ID from user-passed data. + * - Fetches the follow module from the hub. + * - Calls `isFollowing` passing the profile ID, follower & follower token ID and checks it returned true. + * 2. The follow module: + * - Validates the subscription status for that given NFT, reverting on an invalid subscription. + * + * @param profileId The token ID of the profile to validate the follow for. + * @param follower The follower address to validate the follow for. + * @param followNFTTokenId The followNFT token ID to validate the follow for. + * + * @return true if the given address is following the given profile ID, false otherwise. + */ + function isFollowing( + uint256 profileId, + address follower, + uint256 followNFTTokenId + ) external view returns (bool); +} diff --git a/lens-protocol/core/contracts/interfaces/IFollowNFT.sol b/lens-protocol/core/contracts/interfaces/IFollowNFT.sol new file mode 100644 index 0000000..4c899d3 --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/IFollowNFT.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {DataTypes} from '../libraries/DataTypes.sol'; + +/** + * @title IFollowNFT + * @author Lens Protocol + * + * @notice This is the interface for the FollowNFT contract, which is cloned upon the first follow for any profile. + */ +interface IFollowNFT { + /** + * @notice Initializes the follow NFT, setting the hub as the privileged minter and storing the associated profile ID. + * + * @param profileId The token ID of the profile in the hub associated with this followNFT, used for transfer hooks. + */ + function initialize(uint256 profileId) external; + + /** + * @notice Mints a follow NFT to the specified address. This can only be called by the hub, and is called + * upon follow. + * + * @param to The address to mint the NFT to. + * + * @return uint256 An interger representing the minted token ID. + */ + function mint(address to) external returns (uint256); + + /** + * @notice Delegates the caller's governance power to the given delegatee address. + * + * @param delegatee The delegatee address to delegate governance power to. + */ + function delegate(address delegatee) external; + + /** + * @notice Delegates the delegator's governance power via meta-tx to the given delegatee address. + * + * @param delegator The delegator address, who is the signer. + * @param delegatee The delegatee address, who is receiving the governance power delegation. + * @param sig The EIP712Signature struct containing the necessary parameters to recover the delegator's signature. + */ + function delegateBySig( + address delegator, + address delegatee, + DataTypes.EIP712Signature calldata sig + ) external; + + /** + * @notice Returns the governance power for a given user at a specified block number. + * + * @param user The user to query governance power for. + * @param blockNumber The block number to query the user's governance power at. + * + * @return uint256 The power of the given user at the given block number. + */ + function getPowerByBlockNumber(address user, uint256 blockNumber) external view returns (uint256); + + /** + * @notice Returns the total delegated supply at a specified block number. This is the sum of all + * current available voting power at a given block. + * + * @param blockNumber The block number to query the delegated supply at. + * + * @return uint256 The delegated supply at the given block number. + */ + function getDelegatedSupplyByBlockNumber(uint256 blockNumber) external view returns (uint256); +} diff --git a/lens-protocol/core/contracts/interfaces/IKlimaInfinity.sol b/lens-protocol/core/contracts/interfaces/IKlimaInfinity.sol new file mode 100644 index 0000000..8c24294 --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/IKlimaInfinity.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +interface IKlimaInfinity { + // https://github.com/KlimaDAO/klimadao-solidity/blob/main/src/infinity/facets/Retire/RetireSourceFacet.sol#L35 + function retireExactSourceDefault( + address sourceToken, + address poolToken, + uint256 maxAmountIn, + string memory retiringEntityString, + address beneficiaryAddress, + string memory beneficiaryString, + string memory retirementMessage, + uint8 fromMode + ) external payable returns (uint256 retirementIndex); + + /* Views */ + + // https://github.com/KlimaDAO/klimadao-solidity/blob/main/src/infinity/facets/RetirementQuoter.sol#L88 + function getRetireAmountSourceDefault( + address sourceToken, + address carbonToken, + uint amount + ) external view returns (uint amountOut); +} diff --git a/lens-protocol/core/contracts/interfaces/ILensHub.sol b/lens-protocol/core/contracts/interfaces/ILensHub.sol new file mode 100644 index 0000000..adea840 --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/ILensHub.sol @@ -0,0 +1,544 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {DataTypes} from '../libraries/DataTypes.sol'; + +/** + * @title ILensHub + * @author Lens Protocol + * + * @notice This is the interface for the LensHub contract, the main entry point for the Lens Protocol. + * You'll find all the events and external functions, as well as the reasoning behind them here. + */ +interface ILensHub { + /** + * @notice Initializes the LensHub NFT, setting the initial governance address as well as the name and symbol in + * the LensNFTBase contract. + * + * @param name The name to set for the hub NFT. + * @param symbol The symbol to set for the hub NFT. + * @param newGovernance The governance address to set. + */ + function initialize( + string calldata name, + string calldata symbol, + address newGovernance + ) external; + + /** + * @notice Sets the privileged governance role. This function can only be called by the current governance + * address. + * + * @param newGovernance The new governance address to set. + */ + function setGovernance(address newGovernance) external; + + /** + * @notice Sets the emergency admin, which is a permissioned role able to set the protocol state. This function + * can only be called by the governance address. + * + * @param newEmergencyAdmin The new emergency admin address to set. + */ + function setEmergencyAdmin(address newEmergencyAdmin) external; + + /** + * @notice Sets the protocol state to either a global pause, a publishing pause or an unpaused state. This function + * can only be called by the governance address or the emergency admin address. + * + * Note that this reverts if the emergency admin calls it if: + * 1. The emergency admin is attempting to unpause. + * 2. The emergency admin is calling while the protocol is already paused. + * + * @param newState The state to set, as a member of the ProtocolState enum. + */ + function setState(DataTypes.ProtocolState newState) external; + + /** + * @notice Adds or removes a profile creator from the whitelist. This function can only be called by the current + * governance address. + * + * @param profileCreator The profile creator address to add or remove from the whitelist. + * @param whitelist Whether or not the profile creator should be whitelisted. + */ + function whitelistProfileCreator(address profileCreator, bool whitelist) external; + + /** + * @notice Adds or removes a follow module from the whitelist. This function can only be called by the current + * governance address. + * + * @param followModule The follow module contract address to add or remove from the whitelist. + * @param whitelist Whether or not the follow module should be whitelisted. + */ + function whitelistFollowModule(address followModule, bool whitelist) external; + + /** + * @notice Adds or removes a reference module from the whitelist. This function can only be called by the current + * governance address. + * + * @param referenceModule The reference module contract to add or remove from the whitelist. + * @param whitelist Whether or not the reference module should be whitelisted. + */ + function whitelistReferenceModule(address referenceModule, bool whitelist) external; + + /** + * @notice Adds or removes a collect module from the whitelist. This function can only be called by the current + * governance address. + * + * @param collectModule The collect module contract address to add or remove from the whitelist. + * @param whitelist Whether or not the collect module should be whitelisted. + */ + function whitelistCollectModule(address collectModule, bool whitelist) external; + + /** + * @notice Creates a profile with the specified parameters, minting a profile NFT to the given recipient. This + * function must be called by a whitelisted profile creator. + * + * @param vars A CreateProfileData struct containing the following params: + * to: The address receiving the profile. + * handle: The handle to set for the profile, must be unique and non-empty. + * imageURI: The URI to set for the profile image. + * followModule: The follow module to use, can be the zero address. + * followModuleInitData: The follow module initialization data, if any. + */ + function createProfile(DataTypes.CreateProfileData calldata vars) external returns (uint256); + + /** + * @notice Sets the mapping between wallet and its main profile identity. + * + * @param profileId The token ID of the profile to set as the main profile identity. + */ + function setDefaultProfile(uint256 profileId) external; + + /** + * @notice Sets the mapping between wallet and its main profile identity via signature with the specified parameters. + * + * @param vars A SetDefaultProfileWithSigData struct, including the regular parameters and an EIP712Signature struct. + */ + function setDefaultProfileWithSig(DataTypes.SetDefaultProfileWithSigData calldata vars) + external; + + /** + * @notice Sets a profile's follow module, must be called by the profile owner. + * + * @param profileId The token ID of the profile to set the follow module for. + * @param followModule The follow module to set for the given profile, must be whitelisted. + * @param followModuleInitData The data to be passed to the follow module for initialization. + */ + function setFollowModule( + uint256 profileId, + address followModule, + bytes calldata followModuleInitData + ) external; + + /** + * @notice Sets a profile's follow module via signature with the specified parameters. + * + * @param vars A SetFollowModuleWithSigData struct, including the regular parameters and an EIP712Signature struct. + */ + function setFollowModuleWithSig(DataTypes.SetFollowModuleWithSigData calldata vars) external; + + /** + * @notice Sets a profile's dispatcher, giving that dispatcher rights to publish to that profile. + * + * @param profileId The token ID of the profile of the profile to set the dispatcher for. + * @param dispatcher The dispatcher address to set for the given profile ID. + */ + function setDispatcher(uint256 profileId, address dispatcher) external; + + /** + * @notice Sets a profile's dispatcher via signature with the specified parameters. + * + * @param vars A SetDispatcherWithSigData struct, including the regular parameters and an EIP712Signature struct. + */ + function setDispatcherWithSig(DataTypes.SetDispatcherWithSigData calldata vars) external; + + /** + * @notice Sets a profile's URI, which is reflected in the `tokenURI()` function. + * + * @param profileId The token ID of the profile of the profile to set the URI for. + * @param imageURI The URI to set for the given profile. + */ + function setProfileImageURI(uint256 profileId, string calldata imageURI) external; + + /** + * @notice Sets a profile's URI via signature with the specified parameters. + * + * @param vars A SetProfileImageURIWithSigData struct, including the regular parameters and an EIP712Signature struct. + */ + function setProfileImageURIWithSig(DataTypes.SetProfileImageURIWithSigData calldata vars) + external; + + /** + * @notice Sets a followNFT URI for a given profile's follow NFT. + * + * @param profileId The token ID of the profile for which to set the followNFT URI. + * @param followNFTURI The follow NFT URI to set. + */ + function setFollowNFTURI(uint256 profileId, string calldata followNFTURI) external; + + /** + * @notice Sets a followNFT URI via signature with the specified parameters. + * + * @param vars A SetFollowNFTURIWithSigData struct, including the regular parameters and an EIP712Signature struct. + */ + function setFollowNFTURIWithSig(DataTypes.SetFollowNFTURIWithSigData calldata vars) external; + + /** + * @notice Publishes a post to a given profile, must be called by the profile owner. + * + * @param vars A PostData struct containing the needed parameters. + * + * @return uint256 An integer representing the post's publication ID. + */ + function post(DataTypes.PostData calldata vars) external returns (uint256); + + /** + * @notice Publishes a post to a given profile via signature with the specified parameters. + * + * @param vars A PostWithSigData struct containing the regular parameters and an EIP712Signature struct. + * + * @return uint256 An integer representing the post's publication ID. + */ + function postWithSig(DataTypes.PostWithSigData calldata vars) external returns (uint256); + + /** + * @notice Publishes a comment to a given profile, must be called by the profile owner. + * + * @param vars A CommentData struct containing the needed parameters. + * + * @return uint256 An integer representing the comment's publication ID. + */ + function comment(DataTypes.CommentData calldata vars) external returns (uint256); + + /** + * @notice Publishes a comment to a given profile via signature with the specified parameters. + * + * @param vars A CommentWithSigData struct containing the regular parameters and an EIP712Signature struct. + * + * @return uint256 An integer representing the comment's publication ID. + */ + function commentWithSig(DataTypes.CommentWithSigData calldata vars) external returns (uint256); + + /** + * @notice Publishes a mirror to a given profile, must be called by the profile owner. + * + * @param vars A MirrorData struct containing the necessary parameters. + * + * @return uint256 An integer representing the mirror's publication ID. + */ + function mirror(DataTypes.MirrorData calldata vars) external returns (uint256); + + /** + * @notice Publishes a mirror to a given profile via signature with the specified parameters. + * + * @param vars A MirrorWithSigData struct containing the regular parameters and an EIP712Signature struct. + * + * @return uint256 An integer representing the mirror's publication ID. + */ + function mirrorWithSig(DataTypes.MirrorWithSigData calldata vars) external returns (uint256); + + /** + * @notice Follows the given profiles, executing each profile's follow module logic (if any) and minting followNFTs to the caller. + * + * NOTE: Both the `profileIds` and `datas` arrays must be of the same length, regardless if the profiles do not have a follow module set. + * + * @param profileIds The token ID array of the profiles to follow. + * @param datas The arbitrary data array to pass to the follow module for each profile if needed. + * + * @return uint256[] An array of integers representing the minted follow NFTs token IDs. + */ + function follow(uint256[] calldata profileIds, bytes[] calldata datas) + external + returns (uint256[] memory); + + /** + * @notice Follows a given profile via signature with the specified parameters. + * + * @param vars A FollowWithSigData struct containing the regular parameters as well as the signing follower's address + * and an EIP712Signature struct. + * + * @return uint256[] An array of integers representing the minted follow NFTs token IDs. + */ + function followWithSig(DataTypes.FollowWithSigData calldata vars) + external + returns (uint256[] memory); + + /** + * @notice Collects a given publication, executing collect module logic and minting a collectNFT to the caller. + * + * @param profileId The token ID of the profile that published the publication to collect. + * @param pubId The publication to collect's publication ID. + * @param data The arbitrary data to pass to the collect module if needed. + * + * @return uint256 An integer representing the minted token ID. + */ + function collect( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external returns (uint256); + + /** + * @notice Collects a given publication via signature with the specified parameters. + * + * @param vars A CollectWithSigData struct containing the regular parameters as well as the collector's address and + * an EIP712Signature struct. + * + * @return uint256 An integer representing the minted token ID. + */ + function collectWithSig(DataTypes.CollectWithSigData calldata vars) external returns (uint256); + + /** + * @dev Helper function to emit a detailed followNFT transfer event from the hub, to be consumed by frontends to track + * followNFT transfers. + * + * @param profileId The token ID of the profile associated with the followNFT being transferred. + * @param followNFTId The followNFT being transferred's token ID. + * @param from The address the followNFT is being transferred from. + * @param to The address the followNFT is being transferred to. + */ + function emitFollowNFTTransferEvent( + uint256 profileId, + uint256 followNFTId, + address from, + address to + ) external; + + /** + * @dev Helper function to emit a detailed collectNFT transfer event from the hub, to be consumed by frontends to track + * collectNFT transfers. + * + * @param profileId The token ID of the profile associated with the collect NFT being transferred. + * @param pubId The publication ID associated with the collect NFT being transferred. + * @param collectNFTId The collectNFT being transferred's token ID. + * @param from The address the collectNFT is being transferred from. + * @param to The address the collectNFT is being transferred to. + */ + function emitCollectNFTTransferEvent( + uint256 profileId, + uint256 pubId, + uint256 collectNFTId, + address from, + address to + ) external; + + /// ************************ + /// *****VIEW FUNCTIONS***** + /// ************************ + + /** + * @notice Returns whether or not a profile creator is whitelisted. + * + * @param profileCreator The address of the profile creator to check. + * + * @return bool True if the profile creator is whitelisted, false otherwise. + */ + function isProfileCreatorWhitelisted(address profileCreator) external view returns (bool); + + /** + * @notice Returns default profile for a given wallet address + * + * @param wallet The address to find the default mapping + * + * @return uint256 The default profile id, which will be 0 if not mapped. + */ + function defaultProfile(address wallet) external view returns (uint256); + + /** + * @notice Returns whether or not a follow module is whitelisted. + * + * @param followModule The address of the follow module to check. + * + * @return bool True if the the follow module is whitelisted, false otherwise. + */ + function isFollowModuleWhitelisted(address followModule) external view returns (bool); + + /** + * @notice Returns whether or not a reference module is whitelisted. + * + * @param referenceModule The address of the reference module to check. + * + * @return bool True if the the reference module is whitelisted, false otherwise. + */ + function isReferenceModuleWhitelisted(address referenceModule) external view returns (bool); + + /** + * @notice Returns whether or not a collect module is whitelisted. + * + * @param collectModule The address of the collect module to check. + * + * @return bool True if the the collect module is whitelisted, false otherwise. + */ + function isCollectModuleWhitelisted(address collectModule) external view returns (bool); + + /** + * @notice Returns the currently configured governance address. + * + * @return address The address of the currently configured governance. + */ + function getGovernance() external view returns (address); + + /** + * @notice Returns the dispatcher associated with a profile. + * + * @param profileId The token ID of the profile to query the dispatcher for. + * + * @return address The dispatcher address associated with the profile. + */ + function getDispatcher(uint256 profileId) external view returns (address); + + /** + * @notice Returns the publication count for a given profile. + * + * @param profileId The token ID of the profile to query. + * + * @return uint256 The number of publications associated with the queried profile. + */ + function getPubCount(uint256 profileId) external view returns (uint256); + + /** + * @notice Returns the followNFT associated with a given profile, if any. + * + * @param profileId The token ID of the profile to query the followNFT for. + * + * @return address The followNFT associated with the given profile. + */ + function getFollowNFT(uint256 profileId) external view returns (address); + + /** + * @notice Returns the followNFT URI associated with a given profile. + * + * @param profileId The token ID of the profile to query the followNFT URI for. + * + * @return string The followNFT URI associated with the given profile. + */ + function getFollowNFTURI(uint256 profileId) external view returns (string memory); + + /** + * @notice Returns the collectNFT associated with a given publication, if any. + * + * @param profileId The token ID of the profile that published the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return address The address of the collectNFT associated with the queried publication. + */ + function getCollectNFT(uint256 profileId, uint256 pubId) external view returns (address); + + /** + * @notice Returns the follow module associated witha given profile, if any. + * + * @param profileId The token ID of the profile to query the follow module for. + * + * @return address The address of the follow module associated with the given profile. + */ + function getFollowModule(uint256 profileId) external view returns (address); + + /** + * @notice Returns the collect module associated with a given publication. + * + * @param profileId The token ID of the profile that published the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return address The address of the collect module associated with the queried publication. + */ + function getCollectModule(uint256 profileId, uint256 pubId) external view returns (address); + + /** + * @notice Returns the reference module associated witha given profile, if any. + * + * @param profileId The token ID of the profile that published the publication to querythe reference module for. + * @param pubId The publication ID of the publication to query the reference module for. + * + * @return address The address of the reference module associated with the given profile. + */ + function getReferenceModule(uint256 profileId, uint256 pubId) external view returns (address); + + /** + * @notice Returns the handle associated with a profile. + * + * @param profileId The token ID of the profile to query the handle for. + * + * @return string The handle associated with the profile. + */ + function getHandle(uint256 profileId) external view returns (string memory); + + /** + * @notice Returns the publication pointer (profileId & pubId) associated with a given publication. + * + * @param profileId The token ID of the profile that published the publication to query the pointer for. + * @param pubId The publication ID of the publication to query the pointer for. + * + * @return tuple First, the profile ID of the profile the current publication is pointing to, second, the + * publication ID of the publication the current publication is pointing to. + */ + function getPubPointer(uint256 profileId, uint256 pubId) + external + view + returns (uint256, uint256); + + /** + * @notice Returns the URI associated with a given publication. + * + * @param profileId The token ID of the profile that published the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return string The URI associated with a given publication. + */ + function getContentURI(uint256 profileId, uint256 pubId) external view returns (string memory); + + /** + * @notice Returns the profile token ID according to a given handle. + * + * @param handle The handle to resolve the profile token ID with. + * + * @return uint256 The profile ID the passed handle points to. + */ + function getProfileIdByHandle(string calldata handle) external view returns (uint256); + + /** + * @notice Returns the full profile struct associated with a given profile token ID. + * + * @param profileId The token ID of the profile to query. + * + * @return ProfileStruct The profile struct of the given profile. + */ + function getProfile(uint256 profileId) external view returns (DataTypes.ProfileStruct memory); + + /** + * @notice Returns the full publication struct for a given publication. + * + * @param profileId The token ID of the profile that published the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return PublicationStruct The publication struct associated with the queried publication. + */ + function getPub(uint256 profileId, uint256 pubId) + external + view + returns (DataTypes.PublicationStruct memory); + + /** + * @notice Returns the publication type associated with a given publication. + * + * @param profileId The token ID of the profile that published the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return PubType The publication type, as a member of an enum (either "post," "comment" or "mirror"). + */ + function getPubType(uint256 profileId, uint256 pubId) external view returns (DataTypes.PubType); + + /** + * @notice Returns the follow NFT implementation address. + * + * @return address The follow NFT implementation address. + */ + function getFollowNFTImpl() external view returns (address); + + /** + * @notice Returns the collect NFT implementation address. + * + * @return address The collect NFT implementation address. + */ + function getCollectNFTImpl() external view returns (address); +} diff --git a/lens-protocol/core/contracts/interfaces/ILensNFTBase.sol b/lens-protocol/core/contracts/interfaces/ILensNFTBase.sol new file mode 100644 index 0000000..9ccdd1c --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/ILensNFTBase.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {DataTypes} from '../libraries/DataTypes.sol'; + +/** + * @title ILensNFTBase + * @author Lens Protocol + * + * @notice This is the interface for the LensNFTBase contract, from which all Lens NFTs inherit. + * It is an expansion of a very slightly modified ERC721Enumerable contract, which allows expanded + * meta-transaction functionality. + */ +interface ILensNFTBase { + /** + * @notice Implementation of an EIP-712 permit function for an ERC-721 NFT. We don't need to check + * if the tokenId exists, since the function calls ownerOf(tokenId), which reverts if the tokenId does + * not exist. + * + * @param spender The NFT spender. + * @param tokenId The NFT token ID to approve. + * @param sig The EIP712 signature struct. + */ + function permit( + address spender, + uint256 tokenId, + DataTypes.EIP712Signature calldata sig + ) external; + + /** + * @notice Implementation of an EIP-712 permit-style function for ERC-721 operator approvals. Allows + * an operator address to control all NFTs a given owner owns. + * + * @param owner The owner to set operator approvals for. + * @param operator The operator to approve. + * @param approved Whether to approve or revoke approval from the operator. + * @param sig The EIP712 signature struct. + */ + function permitForAll( + address owner, + address operator, + bool approved, + DataTypes.EIP712Signature calldata sig + ) external; + + /** + * @notice Burns an NFT, removing it from circulation and essentially destroying it. This function can only + * be called by the NFT to burn's owner. + * + * @param tokenId The token ID of the token to burn. + */ + function burn(uint256 tokenId) external; + + /** + * @notice Implementation of an EIP-712 permit-style function for token burning. Allows anyone to burn + * a token on behalf of the owner with a signature. + * + * @param tokenId The token ID of the token to burn. + * @param sig The EIP712 signature struct. + */ + function burnWithSig(uint256 tokenId, DataTypes.EIP712Signature calldata sig) external; + + /** + * @notice Returns the domain separator for this NFT contract. + * + * @return bytes32 The domain separator. + */ + function getDomainSeparator() external view returns (bytes32); +} diff --git a/lens-protocol/core/contracts/interfaces/IModuleGlobals.sol b/lens-protocol/core/contracts/interfaces/IModuleGlobals.sol new file mode 100644 index 0000000..4694632 --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/IModuleGlobals.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +/** + * @title IModuleGlobals + * @author Lens Protocol + * + * @notice This is the interface for the ModuleGlobals contract, a data providing contract to be queried by modules + * for the most up-to-date parameters. + */ +interface IModuleGlobals { + /** + * @notice Sets the governance address. This function can only be called by governance. + * + * @param newGovernance The new governance address to set. + */ + function setGovernance(address newGovernance) external; + + /** + * @notice Sets the treasury address. This function can only be called by governance. + * + * @param newTreasury The new treasury address to set. + */ + function setTreasury(address newTreasury) external; + + /** + * @notice Sets the treasury fee. This function can only be called by governance. + * + * @param newTreasuryFee The new treasury fee to set. + */ + function setTreasuryFee(uint16 newTreasuryFee) external; + + /** + * @notice Adds or removes a currency from the whitelist. This function can only be called by governance. + * + * @param currency The currency to add or remove from the whitelist. + * @param toWhitelist Whether to add or remove the currency from the whitelist. + */ + function whitelistCurrency(address currency, bool toWhitelist) external; + + /// ************************ + /// *****VIEW FUNCTIONS***** + /// ************************ + + /** + * @notice Returns whether a currency is whitelisted. + * + * @param currency The currency to query the whitelist for. + * + * @return bool True if the queried currency is whitelisted, false otherwise. + */ + function isCurrencyWhitelisted(address currency) external view returns (bool); + + /** + * @notice Returns the governance address. + * + * @return address The governance address. + */ + function getGovernance() external view returns (address); + + /** + * @notice Returns the treasury address. + * + * @return address The treasury address. + */ + function getTreasury() external view returns (address); + + /** + * @notice Returns the treasury fee. + * + * @return uint16 The treasury fee. + */ + function getTreasuryFee() external view returns (uint16); + + /** + * @notice Returns the treasury address and treasury fee in a single call. + * + * @return tuplee First, the treasury address, second, the treasury fee. + */ + function getTreasuryData() external view returns (address, uint16); +} diff --git a/lens-protocol/core/contracts/interfaces/IReferenceModule.sol b/lens-protocol/core/contracts/interfaces/IReferenceModule.sol new file mode 100644 index 0000000..a24cf70 --- /dev/null +++ b/lens-protocol/core/contracts/interfaces/IReferenceModule.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +/** + * @title IReferenceModule + * @author Lens Protocol + * + * @notice This is the standard interface for all Lens-compatible ReferenceModules. + */ +interface IReferenceModule { + /** + * @notice Initializes data for a given publication being published. This can only be called by the hub. + * @param profileId The token ID of the profile publishing the publication. + * @param pubId The associated publication's LensHub publication ID. + * @param data Arbitrary data passed from the user to be decoded. + * + * @return bytes An abi encoded byte array encapsulating the execution's state changes. This will be emitted by the + * hub alongside the collect module's address and should be consumed by front ends. + */ + function initializeReferenceModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external returns (bytes memory); + + /** + * @notice Processes a comment action referencing a given publication. This can only be called by the hub. + * + * @param profileId The token ID of the profile associated with the publication being published. + * @param profileIdPointed The profile ID of the profile associated the publication being referenced. + * @param pubIdPointed The publication ID of the publication being referenced. + * @param data Arbitrary data __passed from the commenter!__ to be decoded. + */ + function processComment( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external; + + /** + * @notice Processes a mirror action referencing a given publication. This can only be called by the hub. + * + * @param profileId The token ID of the profile associated with the publication being published. + * @param profileIdPointed The profile ID of the profile associated the publication being referenced. + * @param pubIdPointed The publication ID of the publication being referenced. + * @param data Arbitrary data __passed from the mirrorer!__ to be decoded. + */ + function processMirror( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external; +} diff --git a/lens-protocol/core/contracts/libraries/Constants.sol b/lens-protocol/core/contracts/libraries/Constants.sol new file mode 100644 index 0000000..7fb7906 --- /dev/null +++ b/lens-protocol/core/contracts/libraries/Constants.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +library Constants { + string internal constant FOLLOW_NFT_NAME_SUFFIX = '-Follower'; + string internal constant FOLLOW_NFT_SYMBOL_SUFFIX = '-Fl'; + string internal constant COLLECT_NFT_NAME_INFIX = '-Collect-'; + string internal constant COLLECT_NFT_SYMBOL_INFIX = '-Cl-'; + uint8 internal constant MAX_HANDLE_LENGTH = 31; + uint16 internal constant MAX_PROFILE_IMAGE_URI_LENGTH = 6000; +} diff --git a/lens-protocol/core/contracts/libraries/DataTypes.sol b/lens-protocol/core/contracts/libraries/DataTypes.sol new file mode 100644 index 0000000..98818e4 --- /dev/null +++ b/lens-protocol/core/contracts/libraries/DataTypes.sol @@ -0,0 +1,380 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +/** + * @title DataTypes + * @author Lens Protocol + * + * @notice A standard library of data types used throughout the Lens Protocol. + */ +library DataTypes { + /** + * @notice An enum containing the different states the protocol can be in, limiting certain actions. + * + * @param Unpaused The fully unpaused state. + * @param PublishingPaused The state where only publication creation functions are paused. + * @param Paused The fully paused state. + */ + enum ProtocolState { + Unpaused, + PublishingPaused, + Paused + } + + /** + * @notice An enum specifically used in a helper function to easily retrieve the publication type for integrations. + * + * @param Post A standard post, having a URI, a collect module but no pointer to another publication. + * @param Comment A comment, having a URI, a collect module and a pointer to another publication. + * @param Mirror A mirror, having a pointer to another publication, but no URI or collect module. + * @param Nonexistent An indicator showing the queried publication does not exist. + */ + enum PubType { + Post, + Comment, + Mirror, + Nonexistent + } + + /** + * @notice A struct containing the necessary information to reconstruct an EIP-712 typed data signature. + * + * @param v The signature's recovery parameter. + * @param r The signature's r parameter. + * @param s The signature's s parameter + * @param deadline The signature's deadline + */ + struct EIP712Signature { + uint8 v; + bytes32 r; + bytes32 s; + uint256 deadline; + } + + /** + * @notice A struct containing profile data. + * + * @param pubCount The number of publications made to this profile. + * @param followModule The address of the current follow module in use by this profile, can be empty. + * @param followNFT The address of the followNFT associated with this profile, can be empty.. + * @param handle The profile's associated handle. + * @param imageURI The URI to be used for the profile's image. + * @param followNFTURI The URI to be used for the follow NFT. + */ + struct ProfileStruct { + uint256 pubCount; + address followModule; + address followNFT; + string handle; + string imageURI; + string followNFTURI; + } + + /** + * @notice A struct containing data associated with each new publication. + * + * @param profileIdPointed The profile token ID this publication points to, for mirrors and comments. + * @param pubIdPointed The publication ID this publication points to, for mirrors and comments. + * @param contentURI The URI associated with this publication. + * @param referenceModule The address of the current reference module in use by this publication, can be empty. + * @param collectModule The address of the collect module associated with this publication, this exists for all publication. + * @param collectNFT The address of the collectNFT associated with this publication, if any. + */ + struct PublicationStruct { + uint256 profileIdPointed; + uint256 pubIdPointed; + string contentURI; + address referenceModule; + address collectModule; + address collectNFT; + } + + /** + * @notice A struct containing the parameters required for the `createProfile()` function. + * + * @param to The address receiving the profile. + * @param handle The handle to set for the profile, must be unique and non-empty. + * @param imageURI The URI to set for the profile image. + * @param followModule The follow module to use, can be the zero address. + * @param followModuleInitData The follow module initialization data, if any. + * @param followNFTURI The URI to use for the follow NFT. + */ + struct CreateProfileData { + address to; + string handle; + string imageURI; + address followModule; + bytes followModuleInitData; + string followNFTURI; + } + + /** + * @notice A struct containing the parameters required for the `setDefaultProfileWithSig()` function. Parameters are + * the same as the regular `setDefaultProfile()` function, with an added EIP712Signature. + * + * @param wallet The address of the wallet setting the default profile. + * @param profileId The token ID of the profile which will be set as default, or zero. + * @param sig The EIP712Signature struct containing the profile owner's signature. + */ + struct SetDefaultProfileWithSigData { + address wallet; + uint256 profileId; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `setFollowModuleWithSig()` function. Parameters are + * the same as the regular `setFollowModule()` function, with an added EIP712Signature. + * + * @param profileId The token ID of the profile to change the followModule for. + * @param followModule The followModule to set for the given profile, must be whitelisted. + * @param followModuleInitData The data to be passed to the followModule for initialization. + * @param sig The EIP712Signature struct containing the profile owner's signature. + */ + struct SetFollowModuleWithSigData { + uint256 profileId; + address followModule; + bytes followModuleInitData; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `setDispatcherWithSig()` function. Parameters are the same + * as the regular `setDispatcher()` function, with an added EIP712Signature. + * + * @param profileId The token ID of the profile to set the dispatcher for. + * @param dispatcher The dispatcher address to set for the profile. + * @param sig The EIP712Signature struct containing the profile owner's signature. + */ + struct SetDispatcherWithSigData { + uint256 profileId; + address dispatcher; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `setProfileImageURIWithSig()` function. Parameters are the same + * as the regular `setProfileImageURI()` function, with an added EIP712Signature. + * + * @param profileId The token ID of the profile to set the URI for. + * @param imageURI The URI to set for the given profile image. + * @param sig The EIP712Signature struct containing the profile owner's signature. + */ + struct SetProfileImageURIWithSigData { + uint256 profileId; + string imageURI; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `setFollowNFTURIWithSig()` function. Parameters are the same + * as the regular `setFollowNFTURI()` function, with an added EIP712Signature. + * + * @param profileId The token ID of the profile for which to set the followNFT URI. + * @param followNFTURI The follow NFT URI to set. + * @param sig The EIP712Signature struct containing the followNFT's associated profile owner's signature. + */ + struct SetFollowNFTURIWithSigData { + uint256 profileId; + string followNFTURI; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `post()` function. + * + * @param profileId The token ID of the profile to publish to. + * @param contentURI The URI to set for this new publication. + * @param collectModule The collect module to set for this new publication. + * @param collectModuleInitData The data to pass to the collect module's initialization. + * @param referenceModule The reference module to set for the given publication, must be whitelisted. + * @param referenceModuleInitData The data to be passed to the reference module for initialization. + */ + struct PostData { + uint256 profileId; + string contentURI; + address collectModule; + bytes collectModuleInitData; + address referenceModule; + bytes referenceModuleInitData; + } + + /** + * @notice A struct containing the parameters required for the `postWithSig()` function. Parameters are the same as + * the regular `post()` function, with an added EIP712Signature. + * + * @param profileId The token ID of the profile to publish to. + * @param contentURI The URI to set for this new publication. + * @param collectModule The collectModule to set for this new publication. + * @param collectModuleInitData The data to pass to the collectModule's initialization. + * @param referenceModule The reference module to set for the given publication, must be whitelisted. + * @param referenceModuleInitData The data to be passed to the reference module for initialization. + * @param sig The EIP712Signature struct containing the profile owner's signature. + */ + struct PostWithSigData { + uint256 profileId; + string contentURI; + address collectModule; + bytes collectModuleInitData; + address referenceModule; + bytes referenceModuleInitData; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `comment()` function. + * + * @param profileId The token ID of the profile to publish to. + * @param contentURI The URI to set for this new publication. + * @param profileIdPointed The profile token ID to point the comment to. + * @param pubIdPointed The publication ID to point the comment to. + * @param referenceModuleData The data passed to the reference module. + * @param collectModule The collect module to set for this new publication. + * @param collectModuleInitData The data to pass to the collect module's initialization. + * @param referenceModule The reference module to set for the given publication, must be whitelisted. + * @param referenceModuleInitData The data to be passed to the reference module for initialization. + */ + struct CommentData { + uint256 profileId; + string contentURI; + uint256 profileIdPointed; + uint256 pubIdPointed; + bytes referenceModuleData; + address collectModule; + bytes collectModuleInitData; + address referenceModule; + bytes referenceModuleInitData; + } + + /** + * @notice A struct containing the parameters required for the `commentWithSig()` function. Parameters are the same as + * the regular `comment()` function, with an added EIP712Signature. + * + * @param profileId The token ID of the profile to publish to. + * @param contentURI The URI to set for this new publication. + * @param profileIdPointed The profile token ID to point the comment to. + * @param pubIdPointed The publication ID to point the comment to. + * @param referenceModuleData The data passed to the reference module. + * @param collectModule The collectModule to set for this new publication. + * @param collectModuleInitData The data to pass to the collectModule's initialization. + * @param referenceModule The reference module to set for the given publication, must be whitelisted. + * @param referenceModuleInitData The data to be passed to the reference module for initialization. + * @param sig The EIP712Signature struct containing the profile owner's signature. + */ + struct CommentWithSigData { + uint256 profileId; + string contentURI; + uint256 profileIdPointed; + uint256 pubIdPointed; + bytes referenceModuleData; + address collectModule; + bytes collectModuleInitData; + address referenceModule; + bytes referenceModuleInitData; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `mirror()` function. + * + * @param profileId The token ID of the profile to publish to. + * @param profileIdPointed The profile token ID to point the mirror to. + * @param pubIdPointed The publication ID to point the mirror to. + * @param referenceModuleData The data passed to the reference module. + * @param referenceModule The reference module to set for the given publication, must be whitelisted. + * @param referenceModuleInitData The data to be passed to the reference module for initialization. + */ + struct MirrorData { + uint256 profileId; + uint256 profileIdPointed; + uint256 pubIdPointed; + bytes referenceModuleData; + address referenceModule; + bytes referenceModuleInitData; + } + + /** + * @notice A struct containing the parameters required for the `mirrorWithSig()` function. Parameters are the same as + * the regular `mirror()` function, with an added EIP712Signature. + * + * @param profileId The token ID of the profile to publish to. + * @param profileIdPointed The profile token ID to point the mirror to. + * @param pubIdPointed The publication ID to point the mirror to. + * @param referenceModuleData The data passed to the reference module. + * @param referenceModule The reference module to set for the given publication, must be whitelisted. + * @param referenceModuleInitData The data to be passed to the reference module for initialization. + * @param sig The EIP712Signature struct containing the profile owner's signature. + */ + struct MirrorWithSigData { + uint256 profileId; + uint256 profileIdPointed; + uint256 pubIdPointed; + bytes referenceModuleData; + address referenceModule; + bytes referenceModuleInitData; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `followWithSig()` function. Parameters are the same + * as the regular `follow()` function, with the follower's (signer) address and an EIP712Signature added. + * + * @param follower The follower which is the message signer. + * @param profileIds The array of token IDs of the profiles to follow. + * @param datas The array of arbitrary data to pass to the followModules if needed. + * @param sig The EIP712Signature struct containing the follower's signature. + */ + struct FollowWithSigData { + address follower; + uint256[] profileIds; + bytes[] datas; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `collectWithSig()` function. Parameters are the same as + * the regular `collect()` function, with the collector's (signer) address and an EIP712Signature added. + * + * @param collector The collector which is the message signer. + * @param profileId The token ID of the profile that published the publication to collect. + * @param pubId The publication to collect's publication ID. + * @param data The arbitrary data to pass to the collectModule if needed. + * @param sig The EIP712Signature struct containing the collector's signature. + */ + struct CollectWithSigData { + address collector; + uint256 profileId; + uint256 pubId; + bytes data; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `setProfileMetadataWithSig()` function. + * + * @param profileId The profile ID for which to set the metadata. + * @param metadata The metadata string to set for the profile and user. + * @param sig The EIP712Signature struct containing the user's signature. + */ + struct SetProfileMetadataWithSigData { + uint256 profileId; + string metadata; + EIP712Signature sig; + } + + /** + * @notice A struct containing the parameters required for the `toggleFollowWithSig()` function. + * + * @param follower The follower which is the message signer. + * @param profileIds The token ID array of the profiles. + * @param enables The array of booleans to enable/disable follows. + * @param sig The EIP712Signature struct containing the follower's signature. + */ + struct ToggleFollowWithSigData { + address follower; + uint256[] profileIds; + bool[] enables; + EIP712Signature sig; + } +} diff --git a/lens-protocol/core/contracts/libraries/Errors.sol b/lens-protocol/core/contracts/libraries/Errors.sol new file mode 100644 index 0000000..41a5809 --- /dev/null +++ b/lens-protocol/core/contracts/libraries/Errors.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +library Errors { + error CannotInitImplementation(); + error Initialized(); + error SignatureExpired(); + error ZeroSpender(); + error SignatureInvalid(); + error NotOwnerOrApproved(); + error NotHub(); + error TokenDoesNotExist(); + error NotGovernance(); + error NotGovernanceOrEmergencyAdmin(); + error EmergencyAdminCannotUnpause(); + error CallerNotWhitelistedModule(); + error CollectModuleNotWhitelisted(); + error FollowModuleNotWhitelisted(); + error ReferenceModuleNotWhitelisted(); + error ProfileCreatorNotWhitelisted(); + error NotProfileOwner(); + error NotProfileOwnerOrDispatcher(); + error NotDispatcher(); + error PublicationDoesNotExist(); + error HandleTaken(); + error HandleLengthInvalid(); + error HandleContainsInvalidCharacters(); + error HandleFirstCharInvalid(); + error ProfileImageURILengthInvalid(); + error CallerNotFollowNFT(); + error CallerNotCollectNFT(); + error BlockNumberInvalid(); + error ArrayMismatch(); + error CannotCommentOnSelf(); + error NotWhitelisted(); + error InvalidParameter(); + + // Module Errors + error InitParamsInvalid(); + error CollectExpired(); + error FollowInvalid(); + error ModuleDataMismatch(); + error FollowNotApproved(); + error MintLimitExceeded(); + error CollectNotAllowed(); + + // MultiState Errors + error Paused(); + error PublishingPaused(); +} diff --git a/lens-protocol/core/contracts/libraries/Events.sol b/lens-protocol/core/contracts/libraries/Events.sol new file mode 100644 index 0000000..bdd8e59 --- /dev/null +++ b/lens-protocol/core/contracts/libraries/Events.sol @@ -0,0 +1,523 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {DataTypes} from './DataTypes.sol'; + +library Events { + /** + * @dev Emitted when the NFT contract's name and symbol are set at initialization. + * + * @param name The NFT name set. + * @param symbol The NFT symbol set. + * @param timestamp The current block timestamp. + */ + event BaseInitialized(string name, string symbol, uint256 timestamp); + + /** + * @dev Emitted when the hub state is set. + * + * @param caller The caller who set the state. + * @param prevState The previous protocol state, an enum of either `Paused`, `PublishingPaused` or `Unpaused`. + * @param newState The newly set state, an enum of either `Paused`, `PublishingPaused` or `Unpaused`. + * @param timestamp The current block timestamp. + */ + event StateSet( + address indexed caller, + DataTypes.ProtocolState indexed prevState, + DataTypes.ProtocolState indexed newState, + uint256 timestamp + ); + + /** + * @dev Emitted when the governance address is changed. We emit the caller even though it should be the previous + * governance address, as we cannot guarantee this will always be the case due to upgradeability. + * + * @param caller The caller who set the governance address. + * @param prevGovernance The previous governance address. + * @param newGovernance The new governance address set. + * @param timestamp The current block timestamp. + */ + event GovernanceSet( + address indexed caller, + address indexed prevGovernance, + address indexed newGovernance, + uint256 timestamp + ); + + /** + * @dev Emitted when the emergency admin is changed. We emit the caller even though it should be the previous + * governance address, as we cannot guarantee this will always be the case due to upgradeability. + * + * @param caller The caller who set the emergency admin address. + * @param oldEmergencyAdmin The previous emergency admin address. + * @param newEmergencyAdmin The new emergency admin address set. + * @param timestamp The current block timestamp. + */ + event EmergencyAdminSet( + address indexed caller, + address indexed oldEmergencyAdmin, + address indexed newEmergencyAdmin, + uint256 timestamp + ); + + /** + * @dev Emitted when a profile creator is added to or removed from the whitelist. + * + * @param profileCreator The address of the profile creator. + * @param whitelisted Whether or not the profile creator is being added to the whitelist. + * @param timestamp The current block timestamp. + */ + event ProfileCreatorWhitelisted( + address indexed profileCreator, + bool indexed whitelisted, + uint256 timestamp + ); + + /** + * @dev Emitted when a follow module is added to or removed from the whitelist. + * + * @param followModule The address of the follow module. + * @param whitelisted Whether or not the follow module is being added to the whitelist. + * @param timestamp The current block timestamp. + */ + event FollowModuleWhitelisted( + address indexed followModule, + bool indexed whitelisted, + uint256 timestamp + ); + + /** + * @dev Emitted when a reference module is added to or removed from the whitelist. + * + * @param referenceModule The address of the reference module. + * @param whitelisted Whether or not the reference module is being added to the whitelist. + * @param timestamp The current block timestamp. + */ + event ReferenceModuleWhitelisted( + address indexed referenceModule, + bool indexed whitelisted, + uint256 timestamp + ); + + /** + * @dev Emitted when a collect module is added to or removed from the whitelist. + * + * @param collectModule The address of the collect module. + * @param whitelisted Whether or not the collect module is being added to the whitelist. + * @param timestamp The current block timestamp. + */ + event CollectModuleWhitelisted( + address indexed collectModule, + bool indexed whitelisted, + uint256 timestamp + ); + + /** + * @dev Emitted when a profile is created. + * + * @param profileId The newly created profile's token ID. + * @param creator The profile creator, who created the token with the given profile ID. + * @param to The address receiving the profile with the given profile ID. + * @param handle The handle set for the profile. + * @param imageURI The image uri set for the profile. + * @param followModule The profile's newly set follow module. This CAN be the zero address. + * @param followModuleReturnData The data returned from the follow module's initialization. This is abi encoded + * and totally depends on the follow module chosen. + * @param followNFTURI The URI set for the profile's follow NFT. + * @param timestamp The current block timestamp. + */ + event ProfileCreated( + uint256 indexed profileId, + address indexed creator, + address indexed to, + string handle, + string imageURI, + address followModule, + bytes followModuleReturnData, + string followNFTURI, + uint256 timestamp + ); + + /** + * @dev Emitted when a a default profile is set for a wallet as its main identity + * + * @param wallet The wallet which set or unset its default profile. + * @param profileId The token ID of the profile being set as default, or zero. + * @param timestamp The current block timestamp. + */ + event DefaultProfileSet(address indexed wallet, uint256 indexed profileId, uint256 timestamp); + + /** + * @dev Emitted when a dispatcher is set for a specific profile. + * + * @param profileId The token ID of the profile for which the dispatcher is set. + * @param dispatcher The dispatcher set for the given profile. + * @param timestamp The current block timestamp. + */ + event DispatcherSet(uint256 indexed profileId, address indexed dispatcher, uint256 timestamp); + + /** + * @dev Emitted when a profile's URI is set. + * + * @param profileId The token ID of the profile for which the URI is set. + * @param imageURI The URI set for the given profile. + * @param timestamp The current block timestamp. + */ + event ProfileImageURISet(uint256 indexed profileId, string imageURI, uint256 timestamp); + + /** + * @dev Emitted when a follow NFT's URI is set. + * + * @param profileId The token ID of the profile for which the followNFT URI is set. + * @param followNFTURI The follow NFT URI set. + * @param timestamp The current block timestamp. + */ + event FollowNFTURISet(uint256 indexed profileId, string followNFTURI, uint256 timestamp); + + /** + * @dev Emitted when a profile's follow module is set. + * + * @param profileId The profile's token ID. + * @param followModule The profile's newly set follow module. This CAN be the zero address. + * @param followModuleReturnData The data returned from the follow module's initialization. This is abi encoded + * and totally depends on the follow module chosen. + * @param timestamp The current block timestamp. + */ + event FollowModuleSet( + uint256 indexed profileId, + address followModule, + bytes followModuleReturnData, + uint256 timestamp + ); + + /** + * @dev Emitted when a "post" is published. + * + * @param profileId The profile's token ID. + * @param pubId The new publication's ID. + * @param contentURI The URI mapped to this new publication. + * @param collectModule The collect module mapped to this new publication. This CANNOT be the zero address. + * @param collectModuleReturnData The data returned from the collect module's initialization for this given + * publication. This is abi encoded and totally depends on the collect module chosen. + * @param referenceModule The reference module set for this publication. + * @param referenceModuleReturnData The data returned from the reference module at initialization. This is abi + * encoded and totally depends on the reference module chosen. + * @param timestamp The current block timestamp. + */ + event PostCreated( + uint256 indexed profileId, + uint256 indexed pubId, + string contentURI, + address collectModule, + bytes collectModuleReturnData, + address referenceModule, + bytes referenceModuleReturnData, + uint256 timestamp + ); + + /** + * @dev Emitted when a "comment" is published. + * + * @param profileId The profile's token ID. + * @param pubId The new publication's ID. + * @param contentURI The URI mapped to this new publication. + * @param profileIdPointed The profile token ID that this comment points to. + * @param pubIdPointed The publication ID that this comment points to. + * @param referenceModuleData The data passed to the reference module. + * @param collectModule The collect module mapped to this new publication. This CANNOT be the zero address. + * @param collectModuleReturnData The data returned from the collect module's initialization for this given + * publication. This is abi encoded and totally depends on the collect module chosen. + * @param referenceModule The reference module set for this publication. + * @param referenceModuleReturnData The data returned from the reference module at initialization. This is abi + * encoded and totally depends on the reference module chosen. + * @param timestamp The current block timestamp. + */ + event CommentCreated( + uint256 indexed profileId, + uint256 indexed pubId, + string contentURI, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes referenceModuleData, + address collectModule, + bytes collectModuleReturnData, + address referenceModule, + bytes referenceModuleReturnData, + uint256 timestamp + ); + + /** + * @dev Emitted when a "mirror" is published. + * + * @param profileId The profile's token ID. + * @param pubId The new publication's ID. + * @param profileIdPointed The profile token ID that this mirror points to. + * @param pubIdPointed The publication ID that this mirror points to. + * @param referenceModuleData The data passed to the reference module. + * @param referenceModule The reference module set for this publication. + * @param referenceModuleReturnData The data returned from the reference module at initialization. This is abi + * encoded and totally depends on the reference module chosen. + * @param timestamp The current block timestamp. + */ + event MirrorCreated( + uint256 indexed profileId, + uint256 indexed pubId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes referenceModuleData, + address referenceModule, + bytes referenceModuleReturnData, + uint256 timestamp + ); + + /** + * @dev Emitted when a followNFT clone is deployed using a lazy deployment pattern. + * + * @param profileId The token ID of the profile to which this followNFT is associated. + * @param followNFT The address of the newly deployed followNFT clone. + * @param timestamp The current block timestamp. + */ + event FollowNFTDeployed( + uint256 indexed profileId, + address indexed followNFT, + uint256 timestamp + ); + + /** + * @dev Emitted when a collectNFT clone is deployed using a lazy deployment pattern. + * + * @param profileId The publisher's profile token ID. + * @param pubId The publication associated with the newly deployed collectNFT clone's ID. + * @param collectNFT The address of the newly deployed collectNFT clone. + * @param timestamp The current block timestamp. + */ + event CollectNFTDeployed( + uint256 indexed profileId, + uint256 indexed pubId, + address indexed collectNFT, + uint256 timestamp + ); + + /** + * @dev Emitted upon a successful collect action. + * + * @param collector The address collecting the publication. + * @param profileId The token ID of the profile that the collect was initiated towards, useful to differentiate mirrors. + * @param pubId The publication ID that the collect was initiated towards, useful to differentiate mirrors. + * @param rootProfileId The profile token ID of the profile whose publication is being collected. + * @param rootPubId The publication ID of the publication being collected. + * @param collectModuleData The data passed to the collect module. + * @param timestamp The current block timestamp. + */ + event Collected( + address indexed collector, + uint256 indexed profileId, + uint256 indexed pubId, + uint256 rootProfileId, + uint256 rootPubId, + bytes collectModuleData, + uint256 timestamp + ); + + /** + * @dev Emitted upon a successful follow action. + * + * @param follower The address following the given profiles. + * @param profileIds The token ID array of the profiles being followed. + * @param followModuleDatas The array of data parameters passed to each follow module. + * @param timestamp The current block timestamp. + */ + event Followed( + address indexed follower, + uint256[] profileIds, + bytes[] followModuleDatas, + uint256 timestamp + ); + + /** + * @dev Emitted via callback when a followNFT is transferred. + * + * @param profileId The token ID of the profile associated with the followNFT being transferred. + * @param followNFTId The followNFT being transferred's token ID. + * @param from The address the followNFT is being transferred from. + * @param to The address the followNFT is being transferred to. + * @param timestamp The current block timestamp. + */ + event FollowNFTTransferred( + uint256 indexed profileId, + uint256 indexed followNFTId, + address from, + address to, + uint256 timestamp + ); + + /** + * @dev Emitted via callback when a collectNFT is transferred. + * + * @param profileId The token ID of the profile associated with the collectNFT being transferred. + * @param pubId The publication ID associated with the collectNFT being transferred. + * @param collectNFTId The collectNFT being transferred's token ID. + * @param from The address the collectNFT is being transferred from. + * @param to The address the collectNFT is being transferred to. + * @param timestamp The current block timestamp. + */ + event CollectNFTTransferred( + uint256 indexed profileId, + uint256 indexed pubId, + uint256 indexed collectNFTId, + address from, + address to, + uint256 timestamp + ); + + // Collect/Follow NFT-Specific + + /** + * @dev Emitted when a newly deployed follow NFT is initialized. + * + * @param profileId The token ID of the profile connected to this follow NFT. + * @param timestamp The current block timestamp. + */ + event FollowNFTInitialized(uint256 indexed profileId, uint256 timestamp); + + /** + * @dev Emitted when delegation power in a FollowNFT is changed. + * + * @param delegate The delegate whose power has been changed. + * @param newPower The new governance power mapped to the delegate. + * @param timestamp The current block timestamp. + */ + event FollowNFTDelegatedPowerChanged( + address indexed delegate, + uint256 indexed newPower, + uint256 timestamp + ); + + /** + * @dev Emitted when a newly deployed collect NFT is initialized. + * + * @param profileId The token ID of the profile connected to the publication mapped to this collect NFT. + * @param pubId The publication ID connected to the publication mapped to this collect NFT. + * @param timestamp The current block timestamp. + */ + event CollectNFTInitialized( + uint256 indexed profileId, + uint256 indexed pubId, + uint256 timestamp + ); + + // Module-Specific + + /** + * @notice Emitted when the ModuleGlobals governance address is set. + * + * @param prevGovernance The previous governance address. + * @param newGovernance The new governance address set. + * @param timestamp The current block timestamp. + */ + event ModuleGlobalsGovernanceSet( + address indexed prevGovernance, + address indexed newGovernance, + uint256 timestamp + ); + + /** + * @notice Emitted when the ModuleGlobals treasury address is set. + * + * @param prevTreasury The previous treasury address. + * @param newTreasury The new treasury address set. + * @param timestamp The current block timestamp. + */ + event ModuleGlobalsTreasurySet( + address indexed prevTreasury, + address indexed newTreasury, + uint256 timestamp + ); + + /** + * @notice Emitted when the ModuleGlobals treasury fee is set. + * + * @param prevTreasuryFee The previous treasury fee in BPS. + * @param newTreasuryFee The new treasury fee in BPS. + * @param timestamp The current block timestamp. + */ + event ModuleGlobalsTreasuryFeeSet( + uint16 indexed prevTreasuryFee, + uint16 indexed newTreasuryFee, + uint256 timestamp + ); + + /** + * @notice Emitted when a currency is added to or removed from the ModuleGlobals whitelist. + * + * @param currency The currency address. + * @param prevWhitelisted Whether or not the currency was previously whitelisted. + * @param whitelisted Whether or not the currency is whitelisted. + * @param timestamp The current block timestamp. + */ + event ModuleGlobalsCurrencyWhitelisted( + address indexed currency, + bool indexed prevWhitelisted, + bool indexed whitelisted, + uint256 timestamp + ); + + /** + * @notice Emitted when a module inheriting from the `FeeModuleBase` is constructed. + * + * @param moduleGlobals The ModuleGlobals contract address used. + * @param timestamp The current block timestamp. + */ + event FeeModuleBaseConstructed(address indexed moduleGlobals, uint256 timestamp); + + /** + * @notice Emitted when a module inheriting from the `ModuleBase` is constructed. + * + * @param hub The LensHub contract address used. + * @param timestamp The current block timestamp. + */ + event ModuleBaseConstructed(address indexed hub, uint256 timestamp); + + /** + * @notice Emitted when one or multiple addresses are approved (or disapproved) for following in + * the `ApprovalFollowModule`. + * + * @param owner The profile owner who executed the approval. + * @param profileId The profile ID that the follow approvals are granted/revoked for. + * @param addresses The addresses that have had the follow approvals grnated/revoked. + * @param approved Whether each corresponding address is now approved or disapproved. + * @param timestamp The current block timestamp. + */ + event FollowsApproved( + address indexed owner, + uint256 indexed profileId, + address[] addresses, + bool[] approved, + uint256 timestamp + ); + + /** + * @dev Emitted when the user wants to enable or disable follows in the `LensPeriphery`. + * + * @param owner The profile owner who executed the toggle. + * @param profileIds The array of token IDs of the profiles each followNFT is associated with. + * @param enabled The array of whether each FollowNFT's follow is enabled/disabled. + * @param timestamp The current block timestamp. + */ + event FollowsToggled( + address indexed owner, + uint256[] profileIds, + bool[] enabled, + uint256 timestamp + ); + + /** + * @dev Emitted when the metadata associated with a profile is set in the `LensPeriphery`. + * + * @param profileId The profile ID the metadata is set for. + * @param metadata The metadata set for the profile and user. + * @param timestamp The current block timestamp. + */ + event ProfileMetadataSet(uint256 indexed profileId, string metadata, uint256 timestamp); +} diff --git a/lens-protocol/core/contracts/libraries/Helpers.sol b/lens-protocol/core/contracts/libraries/Helpers.sol new file mode 100644 index 0000000..785f3c3 --- /dev/null +++ b/lens-protocol/core/contracts/libraries/Helpers.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {DataTypes} from './DataTypes.sol'; +import {Errors} from './Errors.sol'; + +/** + * @title Helpers + * @author Lens Protocol + * + * @notice This is a library that only contains a single function that is used in the hub contract as well as in + * both the publishing logic and interaction logic libraries. + */ +library Helpers { + /** + * @notice This helper function just returns the pointed publication if the passed publication is a mirror, + * otherwise it returns the passed publication. + * + * @param profileId The token ID of the profile that published the given publication. + * @param pubId The publication ID of the given publication. + * @param _pubByIdByProfile A pointer to the storage mapping of publications by pubId by profile ID. + * + * @return tuple First, the pointed publication's publishing profile ID, second, the pointed publication's ID, and third, the + * pointed publication's collect module. If the passed publication is not a mirror, this returns the given publication. + */ + function getPointedIfMirror( + uint256 profileId, + uint256 pubId, + mapping(uint256 => mapping(uint256 => DataTypes.PublicationStruct)) + storage _pubByIdByProfile + ) + internal + view + returns ( + uint256, + uint256, + address + ) + { + address collectModule = _pubByIdByProfile[profileId][pubId].collectModule; + if (collectModule != address(0)) { + return (profileId, pubId, collectModule); + } else { + uint256 pointedTokenId = _pubByIdByProfile[profileId][pubId].profileIdPointed; + // We validate existence here as an optimization, so validating in calling contracts is unnecessary + if (pointedTokenId == 0) revert Errors.PublicationDoesNotExist(); + + uint256 pointedPubId = _pubByIdByProfile[profileId][pubId].pubIdPointed; + + address pointedCollectModule = _pubByIdByProfile[pointedTokenId][pointedPubId] + .collectModule; + + return (pointedTokenId, pointedPubId, pointedCollectModule); + } + } +} diff --git a/lens-protocol/core/contracts/libraries/InteractionLogic.sol b/lens-protocol/core/contracts/libraries/InteractionLogic.sol new file mode 100644 index 0000000..98b3fc7 --- /dev/null +++ b/lens-protocol/core/contracts/libraries/InteractionLogic.sol @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {FollowNFTProxy} from '../upgradeability/FollowNFTProxy.sol'; +import {Helpers} from './Helpers.sol'; +import {DataTypes} from './DataTypes.sol'; +import {Errors} from './Errors.sol'; +import {Events} from './Events.sol'; +import {Constants} from './Constants.sol'; +import {IFollowNFT} from '../interfaces/IFollowNFT.sol'; +import {ICollectNFT} from '../interfaces/ICollectNFT.sol'; +import {IFollowModule} from '../interfaces/IFollowModule.sol'; +import {ICollectModule} from '../interfaces/ICollectModule.sol'; +import {Clones} from '@openzeppelin/contracts/proxy/Clones.sol'; +import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; + +/** + * @title InteractionLogic + * @author Lens Protocol + * + * @notice This is the library that contains the logic for follows & collects. + + * @dev The functions are external, so they are called from the hub via `delegateCall` under the hood. + */ +library InteractionLogic { + using Strings for uint256; + + /** + * @notice Follows the given profiles, executing the necessary logic and module calls before minting the follow + * NFT(s) to the follower. + * + * @param follower The address executing the follow. + * @param profileIds The array of profile token IDs to follow. + * @param followModuleDatas The array of follow module data parameters to pass to each profile's follow module. + * @param _profileById A pointer to the storage mapping of profile structs by profile ID. + * @param _profileIdByHandleHash A pointer to the storage mapping of profile IDs by handle hash. + * + * @return uint256[] An array of integers representing the minted follow NFTs token IDs. + */ + function follow( + address follower, + uint256[] calldata profileIds, + bytes[] calldata followModuleDatas, + mapping(uint256 => DataTypes.ProfileStruct) storage _profileById, + mapping(bytes32 => uint256) storage _profileIdByHandleHash + ) external returns (uint256[] memory) { + if (profileIds.length != followModuleDatas.length) revert Errors.ArrayMismatch(); + uint256[] memory tokenIds = new uint256[](profileIds.length); + for (uint256 i = 0; i < profileIds.length; ) { + string memory handle = _profileById[profileIds[i]].handle; + if (_profileIdByHandleHash[keccak256(bytes(handle))] != profileIds[i]) + revert Errors.TokenDoesNotExist(); + + address followModule = _profileById[profileIds[i]].followModule; + address followNFT = _profileById[profileIds[i]].followNFT; + + if (followNFT == address(0)) { + followNFT = _deployFollowNFT(profileIds[i]); + _profileById[profileIds[i]].followNFT = followNFT; + } + + tokenIds[i] = IFollowNFT(followNFT).mint(follower); + + if (followModule != address(0)) { + IFollowModule(followModule).processFollow( + follower, + profileIds[i], + followModuleDatas[i] + ); + } + unchecked { + ++i; + } + } + emit Events.Followed(follower, profileIds, followModuleDatas, block.timestamp); + return tokenIds; + } + + /** + * @notice Collects the given publication, executing the necessary logic and module call before minting the + * collect NFT to the collector. + * + * @param collector The address executing the collect. + * @param profileId The token ID of the publication being collected's parent profile. + * @param pubId The publication ID of the publication being collected. + * @param collectModuleData The data to pass to the publication's collect module. + * @param collectNFTImpl The address of the collect NFT implementation, which has to be passed because it's an immutable in the hub. + * @param _pubByIdByProfile A pointer to the storage mapping of publications by pubId by profile ID. + * @param _profileById A pointer to the storage mapping of profile structs by profile ID. + * + * @return uint256 An integer representing the minted token ID. + */ + function collect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata collectModuleData, + address collectNFTImpl, + mapping(uint256 => mapping(uint256 => DataTypes.PublicationStruct)) + storage _pubByIdByProfile, + mapping(uint256 => DataTypes.ProfileStruct) storage _profileById + ) external returns (uint256) { + (uint256 rootProfileId, uint256 rootPubId, address rootCollectModule) = Helpers + .getPointedIfMirror(profileId, pubId, _pubByIdByProfile); + + uint256 tokenId; + // Avoids stack too deep + { + address collectNFT = _pubByIdByProfile[rootProfileId][rootPubId].collectNFT; + if (collectNFT == address(0)) { + collectNFT = _deployCollectNFT( + rootProfileId, + rootPubId, + _profileById[rootProfileId].handle, + collectNFTImpl + ); + _pubByIdByProfile[rootProfileId][rootPubId].collectNFT = collectNFT; + } + tokenId = ICollectNFT(collectNFT).mint(collector); + } + + ICollectModule(rootCollectModule).processCollect( + profileId, + collector, + rootProfileId, + rootPubId, + collectModuleData + ); + _emitCollectedEvent( + collector, + profileId, + pubId, + rootProfileId, + rootPubId, + collectModuleData + ); + + return tokenId; + } + + /** + * @notice Deploys the given profile's Follow NFT contract. + * + * @param profileId The token ID of the profile which Follow NFT should be deployed. + * + * @return address The address of the deployed Follow NFT contract. + */ + function _deployFollowNFT(uint256 profileId) private returns (address) { + bytes memory functionData = abi.encodeWithSelector( + IFollowNFT.initialize.selector, + profileId + ); + address followNFT = address(new FollowNFTProxy(functionData)); + emit Events.FollowNFTDeployed(profileId, followNFT, block.timestamp); + + return followNFT; + } + + /** + * @notice Deploys the given profile's Collect NFT contract. + * + * @param profileId The token ID of the profile which Collect NFT should be deployed. + * @param pubId The publication ID of the publication being collected, which Collect NFT should be deployed. + * @param handle The profile's associated handle. + * @param collectNFTImpl The address of the Collect NFT implementation that should be used for the deployment. + * + * @return address The address of the deployed Collect NFT contract. + */ + function _deployCollectNFT( + uint256 profileId, + uint256 pubId, + string memory handle, + address collectNFTImpl + ) private returns (address) { + address collectNFT = Clones.clone(collectNFTImpl); + + bytes4 firstBytes = bytes4(bytes(handle)); + + string memory collectNFTName = string( + abi.encodePacked(handle, Constants.COLLECT_NFT_NAME_INFIX, pubId.toString()) + ); + string memory collectNFTSymbol = string( + abi.encodePacked(firstBytes, Constants.COLLECT_NFT_SYMBOL_INFIX, pubId.toString()) + ); + + ICollectNFT(collectNFT).initialize(profileId, pubId, collectNFTName, collectNFTSymbol); + emit Events.CollectNFTDeployed(profileId, pubId, collectNFT, block.timestamp); + + return collectNFT; + } + + /** + * @notice Emits the `Collected` event that signals that a successful collect action has occurred. + * + * @dev This is done through this function to prevent stack too deep compilation error. + * + * @param collector The address collecting the publication. + * @param profileId The token ID of the profile that the collect was initiated towards, useful to differentiate mirrors. + * @param pubId The publication ID that the collect was initiated towards, useful to differentiate mirrors. + * @param rootProfileId The profile token ID of the profile whose publication is being collected. + * @param rootPubId The publication ID of the publication being collected. + * @param data The data passed to the collect module. + */ + function _emitCollectedEvent( + address collector, + uint256 profileId, + uint256 pubId, + uint256 rootProfileId, + uint256 rootPubId, + bytes calldata data + ) private { + emit Events.Collected( + collector, + profileId, + pubId, + rootProfileId, + rootPubId, + data, + block.timestamp + ); + } +} diff --git a/lens-protocol/core/contracts/libraries/ProfileTokenURILogic.sol b/lens-protocol/core/contracts/libraries/ProfileTokenURILogic.sol new file mode 100644 index 0000000..bb55c99 --- /dev/null +++ b/lens-protocol/core/contracts/libraries/ProfileTokenURILogic.sol @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import '@openzeppelin/contracts/utils/Base64.sol'; +import '@openzeppelin/contracts/utils/Strings.sol'; + +library ProfileTokenURILogic { + uint8 internal constant DEFAULT_FONT_SIZE = 24; + uint8 internal constant MAX_HANDLE_LENGTH_WITH_DEFAULT_FONT_SIZE = 17; + + /** + * @notice Generates the token URI for the profile NFT. + * + * @dev The decoded token URI JSON metadata contains the following fields: name, description, image and attributes. + * The image field contains a base64-encoded SVG. Both the JSON metadata and the image are generated fully on-chain. + * + * @param id The token ID of the profile. + * @param followers The number of profile's followers. + * @param owner The address which owns the profile. + * @param handle The profile's handle. + * @param imageURI The profile's picture URI. An empty string if has not been set. + * + * @return string The profile's token URI as a base64-encoded JSON string. + */ + function getProfileTokenURI( + uint256 id, + uint256 followers, + address owner, + string memory handle, + string memory imageURI + ) external pure returns (string memory) { + string memory handleWithAtSymbol = string(abi.encodePacked('@', handle)); + return + string( + abi.encodePacked( + 'data:application/json;base64,', + Base64.encode( + abi.encodePacked( + '{"name":"', + handleWithAtSymbol, + '","description":"', + handleWithAtSymbol, + ' - Lens profile","image":"data:image/svg+xml;base64,', + _getSVGImageBase64Encoded(handleWithAtSymbol, imageURI), + '","attributes":[{"trait_type":"id","value":"#', + Strings.toString(id), + '"},{"trait_type":"followers","value":"', + Strings.toString(followers), + '"},{"trait_type":"owner","value":"', + Strings.toHexString(uint160(owner)), + '"},{"trait_type":"handle","value":"', + handleWithAtSymbol, + '"}]}' + ) + ) + ) + ); + } + + /** + * @notice Generates the token image. + * + * @dev If the image URI was set and meets URI format conditions, it will be embedded in the token image. + * Otherwise, a default picture will be used. Handle font size is a function of handle length. + * + * @param handleWithAtSymbol The profile's handle beginning with "@" symbol. + * @param imageURI The profile's picture URI. An empty string if has not been set. + * + * @return string The profile token image as a base64-encoded SVG. + */ + function _getSVGImageBase64Encoded(string memory handleWithAtSymbol, string memory imageURI) + internal + pure + returns (string memory) + { + return + Base64.encode( + abi.encodePacked( + '', + _getSVGProfilePicture(imageURI), + '', + handleWithAtSymbol, + '' + ) + ); + } + + /** + * @notice Gets the fragment of the SVG correponding to the profile picture. + * + * @dev If the image URI was set and meets URI format conditions, this will return an image tag referencing it. + * Otherwise, a group tag that renders the default picture will be returned. + * + * @param imageURI The profile's picture URI. An empty string if has not been set. + * + * @return string The fragment of the SVG token's image correspondending to the profile picture. + */ + function _getSVGProfilePicture(string memory imageURI) internal pure returns (string memory) { + if (_shouldUseCustomPicture(imageURI)) { + return + string( + abi.encodePacked( + '' + ) + ); + } else { + return + ''; + } + } + + /** + * @notice Maps the handle length to a font size. + * + * @dev Gives the font size as a function of handle length using the following formula: + * + * fontSize(handleLength) = 24 when handleLength <= 17 + * fontSize(handleLength) = 24 - (handleLength - 12) / 2 when handleLength > 17 + * + * @param handleLength The profile's handle length. + * @return uint256 The font size. + */ + function _handleLengthToFontSize(uint256 handleLength) internal pure returns (uint256) { + return + handleLength <= MAX_HANDLE_LENGTH_WITH_DEFAULT_FONT_SIZE + ? DEFAULT_FONT_SIZE + : DEFAULT_FONT_SIZE - (handleLength - 12) / 2; + } + + /** + * @notice Decides if Profile NFT should use user provided custom profile picture or the default one. + * + * @dev It checks if there is a custom imageURI set and makes sure it does not contain double-quotes to prevent + * injection attacks through the generated SVG. + * + * @param imageURI The imageURI set by the profile owner. + * + * @return bool A boolean indicating whether custom profile picture should be used or not. + */ + function _shouldUseCustomPicture(string memory imageURI) internal pure returns (bool) { + bytes memory imageURIBytes = bytes(imageURI); + if (imageURIBytes.length == 0) { + return false; + } + uint256 imageURIBytesLength = imageURIBytes.length; + for (uint256 i = 0; i < imageURIBytesLength; ) { + if (imageURIBytes[i] == '"') { + // Avoids embedding a user provided imageURI containing double-quotes to prevent injection attacks + return false; + } + unchecked { + ++i; + } + } + return true; + } +} diff --git a/lens-protocol/core/contracts/libraries/PublishingLogic.sol b/lens-protocol/core/contracts/libraries/PublishingLogic.sol new file mode 100644 index 0000000..d8a60ac --- /dev/null +++ b/lens-protocol/core/contracts/libraries/PublishingLogic.sol @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Helpers} from './Helpers.sol'; +import {DataTypes} from './DataTypes.sol'; +import {Errors} from './Errors.sol'; +import {Events} from './Events.sol'; +import {Constants} from './Constants.sol'; +import {IFollowModule} from '../interfaces/IFollowModule.sol'; +import {ICollectModule} from '../interfaces/ICollectModule.sol'; +import {IReferenceModule} from '../interfaces/IReferenceModule.sol'; + +/** + * @title PublishingLogic + * @author Lens Protocol + * + * @notice This is the library that contains the logic for profile creation & publication. + * + * @dev The functions are external, so they are called from the hub via `delegateCall` under the hood. Furthermore, + * expected events are emitted from this library instead of from the hub to alleviate code size concerns. + */ +library PublishingLogic { + /** + * @notice Executes the logic to create a profile with the given parameters to the given address. + * + * @param vars The CreateProfileData struct containing the following parameters: + * to: The address receiving the profile. + * handle: The handle to set for the profile, must be unique and non-empty. + * imageURI: The URI to set for the profile image. + * followModule: The follow module to use, can be the zero address. + * followModuleInitData: The follow module initialization data, if any + * followNFTURI: The URI to set for the follow NFT. + * @param profileId The profile ID to associate with this profile NFT (token ID). + * @param _profileIdByHandleHash The storage reference to the mapping of profile IDs by handle hash. + * @param _profileById The storage reference to the mapping of profile structs by IDs. + * @param _followModuleWhitelisted The storage reference to the mapping of whitelist status by follow module address. + */ + function createProfile( + DataTypes.CreateProfileData calldata vars, + uint256 profileId, + mapping(bytes32 => uint256) storage _profileIdByHandleHash, + mapping(uint256 => DataTypes.ProfileStruct) storage _profileById, + mapping(address => bool) storage _followModuleWhitelisted + ) external { + _validateHandle(vars.handle); + + if (bytes(vars.imageURI).length > Constants.MAX_PROFILE_IMAGE_URI_LENGTH) + revert Errors.ProfileImageURILengthInvalid(); + + bytes32 handleHash = keccak256(bytes(vars.handle)); + + if (_profileIdByHandleHash[handleHash] != 0) revert Errors.HandleTaken(); + + _profileIdByHandleHash[handleHash] = profileId; + _profileById[profileId].handle = vars.handle; + _profileById[profileId].imageURI = vars.imageURI; + _profileById[profileId].followNFTURI = vars.followNFTURI; + + bytes memory followModuleReturnData; + if (vars.followModule != address(0)) { + _profileById[profileId].followModule = vars.followModule; + followModuleReturnData = _initFollowModule( + profileId, + vars.followModule, + vars.followModuleInitData, + _followModuleWhitelisted + ); + } + + _emitProfileCreated(profileId, vars, followModuleReturnData); + } + + /** + * @notice Sets the follow module for a given profile. + * + * @param profileId The profile ID to set the follow module for. + * @param followModule The follow module to set for the given profile, if any. + * @param followModuleInitData The data to pass to the follow module for profile initialization. + * @param _profile The storage reference to the profile struct associated with the given profile ID. + * @param _followModuleWhitelisted The storage reference to the mapping of whitelist status by follow module address. + */ + function setFollowModule( + uint256 profileId, + address followModule, + bytes calldata followModuleInitData, + DataTypes.ProfileStruct storage _profile, + mapping(address => bool) storage _followModuleWhitelisted + ) external { + if (followModule != _profile.followModule) { + _profile.followModule = followModule; + } + + bytes memory followModuleReturnData; + if (followModule != address(0)) + followModuleReturnData = _initFollowModule( + profileId, + followModule, + followModuleInitData, + _followModuleWhitelisted + ); + emit Events.FollowModuleSet( + profileId, + followModule, + followModuleReturnData, + block.timestamp + ); + } + + /** + * @notice Creates a post publication mapped to the given profile. + * + * @dev To avoid a stack too deep error, reference parameters are passed in memory rather than calldata. + * + * @param profileId The profile ID to associate this publication to. + * @param contentURI The URI to set for this publication. + * @param collectModule The collect module to set for this publication. + * @param collectModuleInitData The data to pass to the collect module for publication initialization. + * @param referenceModule The reference module to set for this publication, if any. + * @param referenceModuleInitData The data to pass to the reference module for publication initialization. + * @param pubId The publication ID to associate with this publication. + * @param _pubByIdByProfile The storage reference to the mapping of publications by publication ID by profile ID. + * @param _collectModuleWhitelisted The storage reference to the mapping of whitelist status by collect module address. + * @param _referenceModuleWhitelisted The storage reference to the mapping of whitelist status by reference module address. + */ + function createPost( + uint256 profileId, + string memory contentURI, + address collectModule, + bytes memory collectModuleInitData, + address referenceModule, + bytes memory referenceModuleInitData, + uint256 pubId, + mapping(uint256 => mapping(uint256 => DataTypes.PublicationStruct)) + storage _pubByIdByProfile, + mapping(address => bool) storage _collectModuleWhitelisted, + mapping(address => bool) storage _referenceModuleWhitelisted + ) external { + _pubByIdByProfile[profileId][pubId].contentURI = contentURI; + + // Collect module initialization + bytes memory collectModuleReturnData = _initPubCollectModule( + profileId, + pubId, + collectModule, + collectModuleInitData, + _pubByIdByProfile, + _collectModuleWhitelisted + ); + + // Reference module initialization + bytes memory referenceModuleReturnData = _initPubReferenceModule( + profileId, + pubId, + referenceModule, + referenceModuleInitData, + _pubByIdByProfile, + _referenceModuleWhitelisted + ); + + emit Events.PostCreated( + profileId, + pubId, + contentURI, + collectModule, + collectModuleReturnData, + referenceModule, + referenceModuleReturnData, + block.timestamp + ); + } + + /** + * @notice Creates a comment publication mapped to the given profile. + * + * @dev This function is unique in that it requires many variables, so, unlike the other publishing functions, + * we need to pass the full CommentData struct in memory to avoid a stack too deep error. + * + * @param vars The CommentData struct to use to create the comment. + * @param pubId The publication ID to associate with this publication. + * @param _profileById The storage reference to the mapping of profile structs by IDs. + * @param _pubByIdByProfile The storage reference to the mapping of publications by publication ID by profile ID. + * @param _collectModuleWhitelisted The storage reference to the mapping of whitelist status by collect module address. + * @param _referenceModuleWhitelisted The storage reference to the mapping of whitelist status by reference module address. + */ + function createComment( + DataTypes.CommentData memory vars, + uint256 pubId, + mapping(uint256 => DataTypes.ProfileStruct) storage _profileById, + mapping(uint256 => mapping(uint256 => DataTypes.PublicationStruct)) + storage _pubByIdByProfile, + mapping(address => bool) storage _collectModuleWhitelisted, + mapping(address => bool) storage _referenceModuleWhitelisted + ) external { + // Validate existence of the pointed publication + uint256 pubCount = _profileById[vars.profileIdPointed].pubCount; + if (pubCount < vars.pubIdPointed || vars.pubIdPointed == 0) + revert Errors.PublicationDoesNotExist(); + + // Ensure the pointed publication is not the comment being created + if (vars.profileId == vars.profileIdPointed && vars.pubIdPointed == pubId) + revert Errors.CannotCommentOnSelf(); + + _pubByIdByProfile[vars.profileId][pubId].contentURI = vars.contentURI; + _pubByIdByProfile[vars.profileId][pubId].profileIdPointed = vars.profileIdPointed; + _pubByIdByProfile[vars.profileId][pubId].pubIdPointed = vars.pubIdPointed; + + // Collect Module Initialization + bytes memory collectModuleReturnData = _initPubCollectModule( + vars.profileId, + pubId, + vars.collectModule, + vars.collectModuleInitData, + _pubByIdByProfile, + _collectModuleWhitelisted + ); + + // Reference module initialization + bytes memory referenceModuleReturnData = _initPubReferenceModule( + vars.profileId, + pubId, + vars.referenceModule, + vars.referenceModuleInitData, + _pubByIdByProfile, + _referenceModuleWhitelisted + ); + + // Reference module validation + address refModule = _pubByIdByProfile[vars.profileIdPointed][vars.pubIdPointed] + .referenceModule; + if (refModule != address(0)) { + IReferenceModule(refModule).processComment( + vars.profileId, + vars.profileIdPointed, + vars.pubIdPointed, + vars.referenceModuleData + ); + } + + // Prevents a stack too deep error + _emitCommentCreated(vars, pubId, collectModuleReturnData, referenceModuleReturnData); + } + + /** + * @notice Creates a mirror publication mapped to the given profile. + * + * @param vars The MirrorData struct to use to create the mirror. + * @param pubId The publication ID to associate with this publication. + * @param _pubByIdByProfile The storage reference to the mapping of publications by publication ID by profile ID. + * @param _referenceModuleWhitelisted The storage reference to the mapping of whitelist status by reference module address. + */ + function createMirror( + DataTypes.MirrorData memory vars, + uint256 pubId, + mapping(uint256 => mapping(uint256 => DataTypes.PublicationStruct)) + storage _pubByIdByProfile, + mapping(address => bool) storage _referenceModuleWhitelisted + ) external { + (uint256 rootProfileIdPointed, uint256 rootPubIdPointed, ) = Helpers.getPointedIfMirror( + vars.profileIdPointed, + vars.pubIdPointed, + _pubByIdByProfile + ); + + _pubByIdByProfile[vars.profileId][pubId].profileIdPointed = rootProfileIdPointed; + _pubByIdByProfile[vars.profileId][pubId].pubIdPointed = rootPubIdPointed; + + // Reference module initialization + bytes memory referenceModuleReturnData = _initPubReferenceModule( + vars.profileId, + pubId, + vars.referenceModule, + vars.referenceModuleInitData, + _pubByIdByProfile, + _referenceModuleWhitelisted + ); + + // Reference module validation + address refModule = _pubByIdByProfile[rootProfileIdPointed][rootPubIdPointed] + .referenceModule; + if (refModule != address(0)) { + IReferenceModule(refModule).processMirror( + vars.profileId, + rootProfileIdPointed, + rootPubIdPointed, + vars.referenceModuleData + ); + } + + emit Events.MirrorCreated( + vars.profileId, + pubId, + rootProfileIdPointed, + rootPubIdPointed, + vars.referenceModuleData, + vars.referenceModule, + referenceModuleReturnData, + block.timestamp + ); + } + + function _initPubCollectModule( + uint256 profileId, + uint256 pubId, + address collectModule, + bytes memory collectModuleInitData, + mapping(uint256 => mapping(uint256 => DataTypes.PublicationStruct)) + storage _pubByIdByProfile, + mapping(address => bool) storage _collectModuleWhitelisted + ) private returns (bytes memory) { + if (!_collectModuleWhitelisted[collectModule]) revert Errors.CollectModuleNotWhitelisted(); + _pubByIdByProfile[profileId][pubId].collectModule = collectModule; + return + ICollectModule(collectModule).initializePublicationCollectModule( + profileId, + pubId, + collectModuleInitData + ); + } + + function _initPubReferenceModule( + uint256 profileId, + uint256 pubId, + address referenceModule, + bytes memory referenceModuleInitData, + mapping(uint256 => mapping(uint256 => DataTypes.PublicationStruct)) + storage _pubByIdByProfile, + mapping(address => bool) storage _referenceModuleWhitelisted + ) private returns (bytes memory) { + if (referenceModule == address(0)) return new bytes(0); + if (!_referenceModuleWhitelisted[referenceModule]) + revert Errors.ReferenceModuleNotWhitelisted(); + _pubByIdByProfile[profileId][pubId].referenceModule = referenceModule; + return + IReferenceModule(referenceModule).initializeReferenceModule( + profileId, + pubId, + referenceModuleInitData + ); + } + + function _initFollowModule( + uint256 profileId, + address followModule, + bytes memory followModuleInitData, + mapping(address => bool) storage _followModuleWhitelisted + ) private returns (bytes memory) { + if (!_followModuleWhitelisted[followModule]) revert Errors.FollowModuleNotWhitelisted(); + return IFollowModule(followModule).initializeFollowModule(profileId, followModuleInitData); + } + + function _emitCommentCreated( + DataTypes.CommentData memory vars, + uint256 pubId, + bytes memory collectModuleReturnData, + bytes memory referenceModuleReturnData + ) private { + emit Events.CommentCreated( + vars.profileId, + pubId, + vars.contentURI, + vars.profileIdPointed, + vars.pubIdPointed, + vars.referenceModuleData, + vars.collectModule, + collectModuleReturnData, + vars.referenceModule, + referenceModuleReturnData, + block.timestamp + ); + } + + function _emitProfileCreated( + uint256 profileId, + DataTypes.CreateProfileData calldata vars, + bytes memory followModuleReturnData + ) internal { + emit Events.ProfileCreated( + profileId, + msg.sender, // Creator is always the msg sender + vars.to, + vars.handle, + vars.imageURI, + vars.followModule, + followModuleReturnData, + vars.followNFTURI, + block.timestamp + ); + } + + function _validateHandle(string calldata handle) private pure { + bytes memory byteHandle = bytes(handle); + if (byteHandle.length == 0 || byteHandle.length > Constants.MAX_HANDLE_LENGTH) + revert Errors.HandleLengthInvalid(); + + uint256 byteHandleLength = byteHandle.length; + for (uint256 i = 0; i < byteHandleLength; ) { + if ( + (byteHandle[i] < '0' || + byteHandle[i] > 'z' || + (byteHandle[i] > '9' && byteHandle[i] < 'a')) && + byteHandle[i] != '.' && + byteHandle[i] != '-' && + byteHandle[i] != '_' + ) revert Errors.HandleContainsInvalidCharacters(); + unchecked { + ++i; + } + } + } +} diff --git a/lens-protocol/core/contracts/misc/AccessControlV1.sol b/lens-protocol/core/contracts/misc/AccessControlV1.sol new file mode 100644 index 0000000..6320632 --- /dev/null +++ b/lens-protocol/core/contracts/misc/AccessControlV1.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {VersionedInitializable} from '../upgradeability/VersionedInitializable.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @title AccessControl + * @author Lens Protocol + * + * @notice This contract enables additional access control for encrypted publications on Lens by reporting whether + * an address owns or has control over a given profile. + */ +contract AccessControl is VersionedInitializable { + uint256 internal constant REVISION = 1; + + address internal immutable LENS_HUB; + + constructor(address _lensHub) { + LENS_HUB = _lensHub; + } + + function initialize() external initializer {} + + /** + * @dev Function used to check whether an address is the owner of a profile. + * + * @param requestorAddress The address to check ownership over a profile. + * @param profileId The ID of the profile being checked for ownership. + * @param data Optional data parameter, which may be used in future upgrades. + * @return Boolean indicating whether address owns the profile or not. + */ + function hasAccess( + address requestorAddress, + uint256 profileId, + bytes memory data + ) external view returns (bool) { + return IERC721(LENS_HUB).ownerOf(profileId) == requestorAddress; + } + + function getRevision() internal pure virtual override returns (uint256) { + return REVISION; + } +} diff --git a/lens-protocol/core/contracts/misc/AccessControlV2.sol b/lens-protocol/core/contracts/misc/AccessControlV2.sol new file mode 100644 index 0000000..a3db46f --- /dev/null +++ b/lens-protocol/core/contracts/misc/AccessControlV2.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {VersionedInitializable} from '../upgradeability/VersionedInitializable.sol'; +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {IFollowModule} from '../interfaces/IFollowModule.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @title AccessControl + * @author Lens Protocol + * + * @notice This contract enables additional access control for encrypted publications on Lens by reporting whether + * an address owns or has control over a given profile. + */ +contract AccessControlV2 is VersionedInitializable { + uint256 internal constant REVISION = 2; + + address internal immutable LENS_HUB; + + constructor(address _lensHub) { + LENS_HUB = _lensHub; + } + + function initialize() external initializer {} + + /** + * @dev Function used to check whether an address is the owner of a profile. + * + * @param requestorAddress The address to check ownership over a profile. + * @param profileId The ID of the profile being checked for ownership. + * @param data Optional data parameter, which may be used in future upgrades. + * @return Boolean indicating whether address owns the profile or not. + */ + function hasAccess( + address requestorAddress, + uint256 profileId, + bytes memory data + ) external view returns (bool) { + return IERC721(LENS_HUB).ownerOf(profileId) == requestorAddress; + } + + function hasCollected( + address requestorAddress, + uint256 publisherId, + uint256 pubId, + uint256 collectorProfileId, + bytes memory data + ) external view returns (bool) { + address collectNFT = ILensHub(LENS_HUB).getCollectNFT(publisherId, pubId); + + return collectNFT != address(0) && IERC721(collectNFT).balanceOf(requestorAddress) > 0; + } + + function isFollowing( + address requestorAddress, + uint256 profileId, + uint256 followerProfileId, + bytes memory data + ) external view returns (bool) { + address followModule = ILensHub(LENS_HUB).getFollowModule(profileId); + bool following; + if (followModule != address(0)) { + following = IFollowModule(followModule).isFollowing(profileId, requestorAddress, 0); + } else { + address followNFT = ILensHub(LENS_HUB).getFollowNFT(profileId); + following = + followNFT != address(0) && + IERC721(followNFT).balanceOf(requestorAddress) != 0; + } + return following || IERC721(LENS_HUB).ownerOf(profileId) == requestorAddress; + } + + function getRevision() internal pure virtual override returns (uint256) { + return REVISION; + } +} diff --git a/lens-protocol/core/contracts/misc/LensPeriphery.sol b/lens-protocol/core/contracts/misc/LensPeriphery.sol new file mode 100644 index 0000000..bd5d068 --- /dev/null +++ b/lens-protocol/core/contracts/misc/LensPeriphery.sol @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IERC721Time} from '../core/base/IERC721Time.sol'; +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {DataTypes} from '../libraries/DataTypes.sol'; +import {Events} from '../libraries/Events.sol'; +import {Errors} from '../libraries/Errors.sol'; + +/** + * @notice This is a peripheral contract that acts as a source of truth for profile metadata and allows + * for users to emit an event demonstrating whether or not they explicitly want a follow to be shown. + * + * @dev This is useful because it allows clients to filter out follow NFTs that were transferred to + * a recipient by another user (i.e. Not a mint) and not register them as "following" unless + * the recipient explicitly toggles the follow here. + */ +contract LensPeriphery { + string public constant NAME = 'LensPeriphery'; + bytes32 internal constant EIP712_REVISION_HASH = keccak256('1'); + bytes32 internal constant EIP712_DOMAIN_TYPEHASH = + keccak256( + 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)' + ); + bytes32 internal constant TOGGLE_FOLLOW_WITH_SIG_TYPEHASH = + keccak256( + 'ToggleFollowWithSig(uint256[] profileIds,bool[] enables,uint256 nonce,uint256 deadline)' + ); + bytes32 internal constant SET_PROFILE_METADATA_WITH_SIG_TYPEHASH = + keccak256( + 'SetProfileMetadataURIWithSig(uint256 profileId,string metadata,uint256 nonce,uint256 deadline)' + ); + + ILensHub public immutable HUB; + + mapping(address => uint256) public sigNonces; + + mapping(uint256 => string) internal _metadataByProfile; + + constructor(ILensHub hub) { + HUB = hub; + } + + /** + * @notice Sets the profile metadata for a given profile. + * + * @param profileId The profile ID to set the metadata for. + * @param metadata The metadata string to set for the profile. + */ + function setProfileMetadataURI(uint256 profileId, string calldata metadata) external { + _validateCallerIsProfileOwnerOrDispatcher(profileId); + _setProfileMetadataURI(profileId, metadata); + } + + /** + * @notice Sets the profile metadata for a given profile via signature with the specified parameters. + * + * @param vars A SetProfileMetadataWithSigData struct containingthe regular parameters and an EIP712Signature struct. + */ + function setProfileMetadataURIWithSig(DataTypes.SetProfileMetadataWithSigData calldata vars) + external + { + unchecked { + address owner = IERC721Time(address(HUB)).ownerOf(vars.profileId); + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + SET_PROFILE_METADATA_WITH_SIG_TYPEHASH, + vars.profileId, + keccak256(bytes(vars.metadata)), + sigNonces[owner]++, + vars.sig.deadline + ) + ) + ), + owner, + vars.sig + ); + } + _setProfileMetadataURI(vars.profileId, vars.metadata); + } + + /** + * @notice Toggle Follows on the given profiles, emiting toggle event for each FollowNFT. + * + * NOTE: `profileIds`, `followNFTIds` and `enables` arrays must be of the same length. + * + * @param profileIds The token ID array of the profiles. + * @param enables The array of booleans to enable/disable follows. + */ + function toggleFollow(uint256[] calldata profileIds, bool[] calldata enables) external { + _toggleFollow(msg.sender, profileIds, enables); + } + + /** + * @notice Toggle Follows a given profiles via signature with the specified parameters. + * + * @param vars A ToggleFollowWithSigData struct containing the regular parameters as well as the signing follower's address + * and an EIP712Signature struct. + */ + function toggleFollowWithSig(DataTypes.ToggleFollowWithSigData calldata vars) external { + unchecked { + _validateRecoveredAddress( + _calculateDigest( + keccak256( + abi.encode( + TOGGLE_FOLLOW_WITH_SIG_TYPEHASH, + keccak256(abi.encodePacked(vars.profileIds)), + keccak256(abi.encodePacked(vars.enables)), + sigNonces[vars.follower]++, + vars.sig.deadline + ) + ) + ), + vars.follower, + vars.sig + ); + } + + _toggleFollow(vars.follower, vars.profileIds, vars.enables); + } + + /** + * @notice Returns the metadata URI of a profile. + * + * @param profileId The profile ID to query the metadata URI for. + * + * @return string The metadata associated with that profile ID, or an empty string if it is not set or the profile does not exist. + */ + function getProfileMetadataURI(uint256 profileId) external view returns (string memory) { + return _metadataByProfile[profileId]; + } + + function _setProfileMetadataURI(uint256 profileId, string calldata metadata) internal { + _metadataByProfile[profileId] = metadata; + emit Events.ProfileMetadataSet(profileId, metadata, block.timestamp); + } + + function _toggleFollow( + address follower, + uint256[] calldata profileIds, + bool[] calldata enables + ) internal { + if (profileIds.length != enables.length) revert Errors.ArrayMismatch(); + uint256 profileIdsLength = profileIds.length; + for (uint256 i = 0; i < profileIdsLength; ) { + address followNFT = HUB.getFollowNFT(profileIds[i]); + if (followNFT == address(0)) revert Errors.FollowInvalid(); + if (!IERC721Time(address(HUB)).exists(profileIds[i])) revert Errors.TokenDoesNotExist(); + if (IERC721Time(followNFT).balanceOf(follower) == 0) revert Errors.FollowInvalid(); + unchecked { + ++i; + } + } + emit Events.FollowsToggled(follower, profileIds, enables, block.timestamp); + } + + function _validateCallerIsProfileOwnerOrDispatcher(uint256 profileId) internal view { + if ( + msg.sender == IERC721Time(address(HUB)).ownerOf(profileId) || + msg.sender == HUB.getDispatcher(profileId) + ) { + return; + } + revert Errors.NotProfileOwnerOrDispatcher(); + } + + /** + * @dev Wrapper for ecrecover to reduce code size, used in meta-tx specific functions. + */ + function _validateRecoveredAddress( + bytes32 digest, + address expectedAddress, + DataTypes.EIP712Signature memory sig + ) internal view { + if (sig.deadline < block.timestamp) revert Errors.SignatureExpired(); + address recoveredAddress = ecrecover(digest, sig.v, sig.r, sig.s); + if (recoveredAddress == address(0) || recoveredAddress != expectedAddress) + revert Errors.SignatureInvalid(); + } + + /** + * @dev Calculates EIP712 DOMAIN_SEPARATOR based on the current contract and chain ID. + */ + function _calculateDomainSeparator() internal view returns (bytes32) { + return + keccak256( + abi.encode( + EIP712_DOMAIN_TYPEHASH, + keccak256(bytes(NAME)), + EIP712_REVISION_HASH, + block.chainid, + address(this) + ) + ); + } + + /** + * @dev Calculates EIP712 digest based on the current DOMAIN_SEPARATOR. + * + * @param hashedMessage The message hash from which the digest should be calculated. + * + * @return bytes32 A 32-byte output representing the EIP712 digest. + */ + function _calculateDigest(bytes32 hashedMessage) internal view returns (bytes32) { + bytes32 digest; + unchecked { + digest = keccak256( + abi.encodePacked('\x19\x01', _calculateDomainSeparator(), hashedMessage) + ); + } + return digest; + } +} diff --git a/lens-protocol/core/contracts/misc/ProfileCreationProxy.sol b/lens-protocol/core/contracts/misc/ProfileCreationProxy.sol new file mode 100644 index 0000000..5d54fa4 --- /dev/null +++ b/lens-protocol/core/contracts/misc/ProfileCreationProxy.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {DataTypes} from '../libraries/DataTypes.sol'; +import {Errors} from '../libraries/Errors.sol'; +import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; + +/** + * @title ProfileCreationProxy + * @author Lens Protocol + * + * @notice This is an ownable proxy contract that enforces ".lens" handle suffixes at profile creation. + * Only the owner can create profiles. + */ +contract ProfileCreationProxy is Ownable { + ILensHub immutable LENS_HUB; + + constructor(address owner, ILensHub hub) { + _transferOwnership(owner); + LENS_HUB = hub; + } + + function proxyCreateProfile(DataTypes.CreateProfileData memory vars) external onlyOwner { + uint256 handleLength = bytes(vars.handle).length; + if (handleLength < 5) revert Errors.HandleLengthInvalid(); + + bytes1 firstByte = bytes(vars.handle)[0]; + if (firstByte == '-' || firstByte == '_' || firstByte == '.') + revert Errors.HandleFirstCharInvalid(); + + for (uint256 i = 1; i < handleLength; ) { + if (bytes(vars.handle)[i] == '.') revert Errors.HandleContainsInvalidCharacters(); + unchecked { + ++i; + } + } + + vars.handle = string(abi.encodePacked(vars.handle, '.lens')); + LENS_HUB.createProfile(vars); + } +} diff --git a/lens-protocol/core/contracts/misc/UIDataProvider.sol b/lens-protocol/core/contracts/misc/UIDataProvider.sol new file mode 100644 index 0000000..5b35d8d --- /dev/null +++ b/lens-protocol/core/contracts/misc/UIDataProvider.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {DataTypes} from '../libraries/DataTypes.sol'; + +/** + * @dev This struct contains both a `ProfileStruct` and a `PublicationStruct`. + * + * @param profileStruct A standard profile struct. + * @param publicationStruct A standard publicationStruct. + */ +struct LatestData { + DataTypes.ProfileStruct profileStruct; + DataTypes.PublicationStruct publicationStruct; +} + +/** + * @title UIDataProvider + * @author Lens Protocol + * + * @dev This is a helper contract to fetch a profile and its latest publication in a single call. + */ +contract UIDataProvider { + ILensHub immutable HUB; + + constructor(ILensHub hub) { + HUB = hub; + } + + /** + * @notice Returns the profile struct and latest publication struct associated with the passed + * profile ID. + * + * @param profileId The profile ID to query. + * + * @return LensData A struct containing the `ProfileStruct` and the `PublicationStruct` queried. + */ + function getLatestDataByProfile(uint256 profileId) external view returns (LatestData memory) { + DataTypes.ProfileStruct memory profileStruct = HUB.getProfile(profileId); + uint256 pubCount = profileStruct.pubCount; + return LatestData(profileStruct, HUB.getPub(profileId, pubCount)); + } + + /** + * @notice Returns the profile struct and latest publication struct associated with the passed + * profile ID. + * + * @param handle The handle to query. + * + * @return LensData A struct containing the `ProfileStruct` and the `PublicationStruct` queried. + */ + function getLatestDataByHandle(string memory handle) external view returns (LatestData memory) { + uint256 profileId = HUB.getProfileIdByHandle(handle); + DataTypes.ProfileStruct memory profileStruct = HUB.getProfile(profileId); + uint256 pubCount = profileStruct.pubCount; + return LatestData(profileStruct, HUB.getPub(profileId, pubCount)); + } +} diff --git a/lens-protocol/core/contracts/mocks/Currency.sol b/lens-protocol/core/contracts/mocks/Currency.sol new file mode 100644 index 0000000..0bd0f94 --- /dev/null +++ b/lens-protocol/core/contracts/mocks/Currency.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; + +contract Currency is ERC20('Currency', 'CRNC') { + function mint(address to, uint256 amount) external { + _mint(to, amount); + } +} diff --git a/lens-protocol/core/contracts/mocks/Helper.sol b/lens-protocol/core/contracts/mocks/Helper.sol new file mode 100644 index 0000000..9d7f63c --- /dev/null +++ b/lens-protocol/core/contracts/mocks/Helper.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IFollowNFT} from '../interfaces/IFollowNFT.sol'; + +/** + * @dev This is a helper contract used for internal testing. + * + * NOTE: This contract is not meant to be deployed and is unsafe for use. + */ +contract Helper { + /** + * @dev This is a helper function that exposes the block number due to the inconsistency of + * fetching the block number from scripts. + */ + function getBlockNumber() external view returns (uint256) { + return block.number; + } + + /** + * @dev This is a helper function to aid in testing same-block delegation in the FollowNFT contract. + */ + function batchDelegate( + IFollowNFT nft, + address first, + address second + ) external { + nft.delegate(first); + nft.delegate(second); + } +} diff --git a/lens-protocol/core/contracts/mocks/MockAccessControlV2BadRevision.sol b/lens-protocol/core/contracts/mocks/MockAccessControlV2BadRevision.sol new file mode 100644 index 0000000..ec356a1 --- /dev/null +++ b/lens-protocol/core/contracts/mocks/MockAccessControlV2BadRevision.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {VersionedInitializable} from '../upgradeability/VersionedInitializable.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @title MockAccessControlV2BadRevision + * @author Lens Protocol + * + * @notice This contract enables additional access control for encrypted publications on Lens by reporting whether + * an address owns or has control over a given profile. + */ +contract MockAccessControlV2BadRevision is VersionedInitializable { + uint256 internal constant REVISION = 1; + + address internal immutable LENS_HUB; + + uint256 public randomNumber = 7; // contract must be different to original + + constructor(address _lensHub) { + LENS_HUB = _lensHub; + } + + function initialize() external initializer {} + + /** + * @dev Function used to check whether an address is the owner of a profile. + * + * @param requestorAddress The address to check ownership over a profile. + * @param profileId The ID of the profile being checked for ownership. + * @param data Optional data parameter, which may be used in future upgrades. + * @return Boolean indicating whether address owns the profile or not. + */ + function hasAccess( + address requestorAddress, + uint256 profileId, + bytes memory data + ) external view returns (bool) { + return IERC721(LENS_HUB).ownerOf(profileId) == requestorAddress; + } + + function getRevision() internal pure virtual override returns (uint256) { + return REVISION; + } +} diff --git a/lens-protocol/core/contracts/mocks/MockFollowModule.sol b/lens-protocol/core/contracts/mocks/MockFollowModule.sol new file mode 100644 index 0000000..466bb13 --- /dev/null +++ b/lens-protocol/core/contracts/mocks/MockFollowModule.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IFollowModule} from '../interfaces/IFollowModule.sol'; + +contract MockFollowModule is IFollowModule { + function initializeFollowModule(uint256 profileId, bytes calldata data) + external + pure + override + returns (bytes memory) + { + uint256 number = abi.decode(data, (uint256)); + require(number == 1, 'MockFollowModule: invalid'); + return new bytes(0); + } + + function processFollow( + address follower, + uint256 profileId, + bytes calldata data + ) external override {} + + function isFollowing( + uint256 profileId, + address follower, + uint256 followNFTTokenId + ) external view override returns (bool) { + return true; + } + + function followModuleTransferHook( + uint256 profileId, + address from, + address to, + uint256 followNFTTokenId + ) external override {} +} diff --git a/lens-protocol/core/contracts/mocks/MockLensHubV2.sol b/lens-protocol/core/contracts/mocks/MockLensHubV2.sol new file mode 100644 index 0000000..7ba7a3e --- /dev/null +++ b/lens-protocol/core/contracts/mocks/MockLensHubV2.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {Events} from '../libraries/Events.sol'; +import {Helpers} from '../libraries/Helpers.sol'; +import {DataTypes} from '../libraries/DataTypes.sol'; +import {Errors} from '../libraries/Errors.sol'; +import {PublishingLogic} from '../libraries/PublishingLogic.sol'; +import {InteractionLogic} from '../libraries/InteractionLogic.sol'; +import {LensNFTBase} from '../core/base/LensNFTBase.sol'; +import {LensMultiState} from '../core/base/LensMultiState.sol'; +import {VersionedInitializable} from '../upgradeability/VersionedInitializable.sol'; +import {MockLensHubV2Storage} from './MockLensHubV2Storage.sol'; + +/** + * @dev A mock upgraded LensHub contract that is used mainly to validate that the initializer works as expected and + * that the storage layout after an upgrade is valid. + */ +contract MockLensHubV2 is + LensNFTBase, + VersionedInitializable, + LensMultiState, + MockLensHubV2Storage +{ + uint256 internal constant REVISION = 2; + + function initialize(uint256 newValue) external initializer { + _additionalValue = newValue; + } + + function setAdditionalValue(uint256 newValue) external { + _additionalValue = newValue; + } + + function getAdditionalValue() external view returns (uint256) { + return _additionalValue; + } + + function getRevision() internal pure virtual override returns (uint256) { + return REVISION; + } +} diff --git a/lens-protocol/core/contracts/mocks/MockLensHubV2BadRevision.sol b/lens-protocol/core/contracts/mocks/MockLensHubV2BadRevision.sol new file mode 100644 index 0000000..a997464 --- /dev/null +++ b/lens-protocol/core/contracts/mocks/MockLensHubV2BadRevision.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {Events} from '../libraries/Events.sol'; +import {Helpers} from '../libraries/Helpers.sol'; +import {DataTypes} from '../libraries/DataTypes.sol'; +import {Errors} from '../libraries/Errors.sol'; +import {PublishingLogic} from '../libraries/PublishingLogic.sol'; +import {InteractionLogic} from '../libraries/InteractionLogic.sol'; +import {LensNFTBase} from '../core/base/LensNFTBase.sol'; +import {LensMultiState} from '../core/base/LensMultiState.sol'; +import {VersionedInitializable} from '../upgradeability/VersionedInitializable.sol'; +import {MockLensHubV2Storage} from './MockLensHubV2Storage.sol'; + +/** + * @dev A mock upgraded LensHub contract that is used to validate that the initializer cannot be called with the same revision. + */ +contract MockLensHubV2BadRevision is + LensNFTBase, + VersionedInitializable, + LensMultiState, + MockLensHubV2Storage +{ + uint256 internal constant REVISION = 1; // Should fail the initializer check + + function initialize(uint256 newValue) external initializer { + _additionalValue = newValue; + } + + function setAdditionalValue(uint256 newValue) external { + _additionalValue = newValue; + } + + function getAdditionalValue() external view returns (uint256) { + return _additionalValue; + } + + function getRevision() internal pure virtual override returns (uint256) { + return REVISION; + } +} diff --git a/lens-protocol/core/contracts/mocks/MockLensHubV2Storage.sol b/lens-protocol/core/contracts/mocks/MockLensHubV2Storage.sol new file mode 100644 index 0000000..c7371b7 --- /dev/null +++ b/lens-protocol/core/contracts/mocks/MockLensHubV2Storage.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +import {DataTypes} from '../libraries/DataTypes.sol'; + +contract MockLensHubV2Storage { + bytes32 internal constant CREATE_PROFILE_WITH_SIG_TYPEHASH = + 0x9ac3269d9abd6f8c5e850e07f21b199079e8a5cc4a55466d8c96ab0c4a5be403; + // keccak256( + // 'CreateProfileWithSig(string handle,string uri,address followModule,bytes followModuleData,uint256 nonce,uint256 deadline)' + // ); + bytes32 internal constant SET_FOLLOW_MODULE_WITH_SIG_TYPEHASH = + 0x6f3f6455a608af1cc57ef3e5c0a49deeb88bba264ec8865b798ff07358859d4b; + // keccak256( + // 'SetFollowModuleWithSig(uint256 profileId,address followModule,bytes followModuleData,uint256 nonce,uint256 deadline)' + // ); + bytes32 internal constant SET_DISPATCHER_WITH_SIG_TYPEHASH = + 0x77ba3e9f5fa75343bbad1241fb539a0064de97694b47d463d1eb5c54aba11f0f; + // keccak256( + // 'SetDispatcherWithSig(uint256 profileId,address dispatcher,uint256 nonce,uint256 deadline)' + // ); + bytes32 internal constant SET_PROFILE_IMAGE_URI_WITH_SIG_TYPEHASH = + 0x5b9860bd835e648945b22d053515bc1f53b7d9fab4b23b1b49db15722e945d14; + // keccak256( + // 'SetProfileImageURIWithSig(uint256 profileId,string imageURI,uint256 nonce,uint256 deadline)' + // ); + bytes32 internal constant POST_WITH_SIG_TYPEHASH = + 0xfb8f057542e7551386ead0b891a45f102af78c47f8cc58b4a919c7cfeccd0e1e; + // keccak256( + // 'PostWithSig(uint256 profileId,string contentURI,address collectModule,bytes collectModuleData,address referenceModule,bytes referenceModuleData,uint256 nonce,uint256 deadline)' + // ); + bytes32 internal constant COMMENT_WITH_SIG_TYPEHASH = + 0xb30910150df56294e05b2d03e181803697a2b935abb1b9bdddde9310f618fe9b; + // keccak256( + // 'CommentWithSig(uint256 profileId,string contentURI,uint256 profileIdPointed,uint256 pubIdPointed,address collectModule,bytes collectModuleData,address referenceModule,bytes referenceModuleData,uint256 nonce,uint256 deadline)' + // ); + bytes32 internal constant MIRROR_WITH_SIG_TYPEHASH = + 0x64f4578fc098f96a2450fbe601cb8c5318ebeb2ff72d2031a36be1ff6932d5ee; + // keccak256( + // 'MirrorWithSig(uint256 profileId,uint256 profileIdPointed,uint256 pubIdPointed,address referenceModule,bytes referenceModuleData,uint256 nonce,uint256 deadline)' + // ); + bytes32 internal constant FOLLOW_WITH_SIG_TYPEHASH = + 0xfb6b7f1cd1b38daf3822aff0abbe78124db5d62a4748bcff007c15ccd6d30bc5; + // keccak256( + // 'FollowWithSig(uint256[] profileIds,bytes[] datas,uint256 nonce,uint256 deadline)' + // ); + bytes32 internal constant COLLECT_WITH_SIG_TYPEHASH = + 0x7f9b4ea1fc678b4fda1611ac5cbd28f339e235d89b1540635e9b2e0223a3c101; + // keccak256( + // 'CollectWithSig(uint256 profileId,uint256 pubId,bytes data,uint256 nonce,uint256 deadline)' + // ); + + mapping(address => bool) internal _followModuleWhitelisted; + mapping(address => bool) internal _collectModuleWhitelisted; + mapping(address => bool) internal _referenceModuleWhitelisted; + + mapping(uint256 => address) internal _dispatcherByProfile; + mapping(bytes32 => uint256) internal _profileIdByHandleHash; + mapping(uint256 => DataTypes.ProfileStruct) internal _profileById; + mapping(uint256 => mapping(uint256 => DataTypes.PublicationStruct)) internal _pubByIdByProfile; + + mapping(address => uint256) internal _defaultProfileByAddress; + + uint256 internal _profileCounter; + address internal _governance; + address internal _emergencyAdmin; + uint256 internal _additionalValue; +} diff --git a/lens-protocol/core/contracts/mocks/MockProfileCreationProxy.sol b/lens-protocol/core/contracts/mocks/MockProfileCreationProxy.sol new file mode 100644 index 0000000..3026d50 --- /dev/null +++ b/lens-protocol/core/contracts/mocks/MockProfileCreationProxy.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {DataTypes} from '../libraries/DataTypes.sol'; +import {Errors} from '../libraries/Errors.sol'; + +/** + * @title MockProfileCreationProxy + * @author Lens Protocol + * + * @notice This is a proxy contract that enforces ".test" handle suffixes and adds char validations at profile creation. + */ +contract MockProfileCreationProxy { + ILensHub immutable LENS_HUB; + + constructor(ILensHub hub) { + LENS_HUB = hub; + } + + function proxyCreateProfile(DataTypes.CreateProfileData memory vars) external { + uint256 handleLength = bytes(vars.handle).length; + if (handleLength < 5) revert Errors.HandleLengthInvalid(); + + bytes1 firstByte = bytes(vars.handle)[0]; + if (firstByte == '-' || firstByte == '_' || firstByte == '.') + revert Errors.HandleFirstCharInvalid(); + + for (uint256 i = 1; i < handleLength; ) { + if (bytes(vars.handle)[i] == '.') revert Errors.HandleContainsInvalidCharacters(); + unchecked { + ++i; + } + } + + vars.handle = string(abi.encodePacked(vars.handle, '.test')); + LENS_HUB.createProfile(vars); + } +} diff --git a/lens-protocol/core/contracts/mocks/MockReferenceModule.sol b/lens-protocol/core/contracts/mocks/MockReferenceModule.sol new file mode 100644 index 0000000..50ccf88 --- /dev/null +++ b/lens-protocol/core/contracts/mocks/MockReferenceModule.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IReferenceModule} from '../interfaces/IReferenceModule.sol'; + +contract MockReferenceModule is IReferenceModule { + function initializeReferenceModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external pure override returns (bytes memory) { + uint256 number = abi.decode(data, (uint256)); + require(number == 1, 'MockReferenceModule: invalid'); + return new bytes(0); + } + + function processComment( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external override {} + + function processMirror( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external override {} +} diff --git a/lens-protocol/core/contracts/upgradeability/FollowNFTProxy.sol b/lens-protocol/core/contracts/upgradeability/FollowNFTProxy.sol new file mode 100644 index 0000000..f123fdb --- /dev/null +++ b/lens-protocol/core/contracts/upgradeability/FollowNFTProxy.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ILensHub} from '../interfaces/ILensHub.sol'; +import {Proxy} from '@openzeppelin/contracts/proxy/Proxy.sol'; +import {Address} from '@openzeppelin/contracts/utils/Address.sol'; + +contract FollowNFTProxy is Proxy { + using Address for address; + address immutable HUB; + + constructor(bytes memory data) { + HUB = msg.sender; + ILensHub(msg.sender).getFollowNFTImpl().functionDelegateCall(data); + } + + function _implementation() internal view override returns (address) { + return ILensHub(HUB).getFollowNFTImpl(); + } +} diff --git a/lens-protocol/core/contracts/upgradeability/TransparentUpgradeableProxy.sol b/lens-protocol/core/contracts/upgradeability/TransparentUpgradeableProxy.sol new file mode 100644 index 0000000..b7aca36 --- /dev/null +++ b/lens-protocol/core/contracts/upgradeability/TransparentUpgradeableProxy.sol @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.0 (proxy/transparent/TransparentUpgradeableProxy.sol) + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +/** + * NOTE: This is a direct copy of OpenZeppelin's TransparentUpgradeableProxy and is only present for + * ease of explorer verification. + * + * @dev This contract implements a proxy that is upgradeable by an admin. + * + * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector + * clashing], which can potentially be used in an attack, this contract uses the + * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two + * things that go hand in hand: + * + * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if + * that call matches one of the admin functions exposed by the proxy itself. + * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the + * implementation. If the admin tries to call a function on the implementation it will fail with an error that says + * "admin cannot fallback to proxy target". + * + * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing + * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due + * to sudden errors when trying to call a function from the proxy implementation. + * + * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, + * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy. + */ +contract TransparentUpgradeableProxy is ERC1967Proxy { + /** + * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and + * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. + */ + constructor( + address _logic, + address admin_, + bytes memory _data + ) payable ERC1967Proxy(_logic, _data) { + assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)); + _changeAdmin(admin_); + } + + /** + * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. + */ + modifier ifAdmin() { + if (msg.sender == _getAdmin()) { + _; + } else { + _fallback(); + } + } + + /** + * @dev Returns the current admin. + * + * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. + * + * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the + * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. + * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` + */ + function admin() external ifAdmin returns (address admin_) { + admin_ = _getAdmin(); + } + + /** + * @dev Returns the current implementation. + * + * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. + * + * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the + * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. + * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` + */ + function implementation() external ifAdmin returns (address implementation_) { + implementation_ = _implementation(); + } + + /** + * @dev Changes the admin of the proxy. + * + * Emits an {AdminChanged} event. + * + * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}. + */ + function changeAdmin(address newAdmin) external virtual ifAdmin { + _changeAdmin(newAdmin); + } + + /** + * @dev Upgrade the implementation of the proxy. + * + * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. + */ + function upgradeTo(address newImplementation) external ifAdmin { + _upgradeToAndCall(newImplementation, bytes(""), false); + } + + /** + * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified + * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the + * proxied contract. + * + * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}. + */ + function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin { + _upgradeToAndCall(newImplementation, data, true); + } + + /** + * @dev Returns the current admin. + */ + function _admin() internal view virtual returns (address) { + return _getAdmin(); + } + + /** + * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}. + */ + function _beforeFallback() internal virtual override { + require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target"); + super._beforeFallback(); + } +} diff --git a/lens-protocol/core/contracts/upgradeability/VersionedInitializable.sol b/lens-protocol/core/contracts/upgradeability/VersionedInitializable.sol new file mode 100644 index 0000000..320fdc9 --- /dev/null +++ b/lens-protocol/core/contracts/upgradeability/VersionedInitializable.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +import {Errors} from '../libraries/Errors.sol'; + +/** + * @title VersionedInitializable + * + * @dev Helper contract to implement initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + * + * This is slightly modified from [Aave's version.](https://github.com/aave/protocol-v2/blob/6a503eb0a897124d8b9d126c915ffdf3e88343a9/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol) + * + * @author Lens Protocol, inspired by Aave's implementation, which is in turn inspired by OpenZeppelin's + * Initializable contract + */ +abstract contract VersionedInitializable { + address private immutable originalImpl; + + /** + * @dev Indicates that the contract has been initialized. + */ + uint256 private lastInitializedRevision = 0; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + uint256 revision = getRevision(); + if (address(this) == originalImpl) revert Errors.CannotInitImplementation(); + if (revision <= lastInitializedRevision) revert Errors.Initialized(); + lastInitializedRevision = revision; + _; + } + + constructor() { + originalImpl = address(this); + } + + /** + * @dev returns the revision number of the contract + * Needs to be defined in the inherited class as a constant. + **/ + function getRevision() internal pure virtual returns (uint256); +} diff --git a/lens-protocol/core/docker-compose.yml b/lens-protocol/core/docker-compose.yml new file mode 100644 index 0000000..2e5a374 --- /dev/null +++ b/lens-protocol/core/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3.5' + +services: + contracts-env: + user: "${USERID?}:${USERID?}" + env_file: + - .env + build: + context: ./ + stdin_open: true + tty: true + volumes: + - ./:/src:rw + - $HOME/.tenderly/config.yaml:/root/.tenderly/config.yaml:ro + #environment: + #- MNEMONIC= + #- RPC_URL= + #- BLOCK_EXPLORER_KEY= + #- TENDERLY_PROJECT= + #- TENDERLY_USERNAME= + #- TENDERLY_FORK_ID= + #- TENDERLY_HEAD_ID= diff --git a/lens-protocol/core/docker-entrypoint.sh b/lens-protocol/core/docker-entrypoint.sh new file mode 100644 index 0000000..4a1d5f6 --- /dev/null +++ b/lens-protocol/core/docker-entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +[ ! -d "/src/node_modules" ] && cp /node_modules /src/node_modules; bash diff --git a/lens-protocol/core/hardhat.config.ts b/lens-protocol/core/hardhat.config.ts new file mode 100644 index 0000000..b6fd8a6 --- /dev/null +++ b/lens-protocol/core/hardhat.config.ts @@ -0,0 +1,112 @@ +import { HardhatUserConfig } from 'hardhat/types'; +import { accounts } from './helpers/test-wallets'; +import { eEthereumNetwork, eNetwork, ePolygonNetwork, eXDaiNetwork } from './helpers/types'; +import { HARDHATEVM_CHAINID } from './helpers/hardhat-constants'; +import { NETWORKS_RPC_URL } from './helper-hardhat-config'; +import dotenv from 'dotenv'; +import glob from 'glob'; +import path from 'path'; +dotenv.config({ path: '../.env' }); + +import '@nomiclabs/hardhat-ethers'; +import '@nomiclabs/hardhat-etherscan'; +import '@typechain/hardhat'; +import 'solidity-coverage'; +import 'hardhat-gas-reporter'; +import 'hardhat-contract-sizer'; +import 'hardhat-log-remover'; +import 'hardhat-spdx-license-identifier'; + +if (!process.env.SKIP_LOAD) { + glob.sync('./tasks/**/*.ts').forEach(function (file) { + require(path.resolve(file)); + }); +} + +const DEFAULT_BLOCK_GAS_LIMIT = 12450000; +const MNEMONIC_PATH = "m/44'/60'/0'/0"; +const MNEMONIC = process.env.MNEMONIC || ''; +const MAINNET_FORK = process.env.MAINNET_FORK === 'true'; +const TRACK_GAS = process.env.TRACK_GAS === 'true'; +const BLOCK_EXPLORER_KEY = process.env.BLOCK_EXPLORER_KEY || ''; + +const getCommonNetworkConfig = (networkName: eNetwork, networkId: number) => ({ + url: NETWORKS_RPC_URL[networkName] ?? '', + accounts: { + mnemonic: MNEMONIC, + path: MNEMONIC_PATH, + initialIndex: 0, + count: 20, + }, +}); + +const mainnetFork = MAINNET_FORK + ? { + blockNumber: 12012081, + url: NETWORKS_RPC_URL['main'], + } + : undefined; + +const config: HardhatUserConfig = { + solidity: { + compilers: [ + { + version: '0.8.10', + settings: { + optimizer: { + enabled: true, + runs: 200, + details: { + yul: true, + }, + }, + }, + }, + ], + }, + networks: { + kovan: getCommonNetworkConfig(eEthereumNetwork.kovan, 42), + ropsten: getCommonNetworkConfig(eEthereumNetwork.ropsten, 3), + main: getCommonNetworkConfig(eEthereumNetwork.main, 1), + tenderlyMain: getCommonNetworkConfig(eEthereumNetwork.tenderlyMain, 3030), + matic: getCommonNetworkConfig(ePolygonNetwork.matic, 137), + sandbox: getCommonNetworkConfig(ePolygonNetwork.mumbai, 80001), + mumbai: getCommonNetworkConfig(ePolygonNetwork.mumbai, 80001), + xdai: getCommonNetworkConfig(eXDaiNetwork.xdai, 100), + hardhat: { + hardfork: 'london', + blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT, + gas: DEFAULT_BLOCK_GAS_LIMIT, + gasPrice: 8000000000, + chainId: HARDHATEVM_CHAINID, + throwOnTransactionFailures: true, + throwOnCallFailures: true, + accounts: accounts.map(({ secretKey, balance }: { secretKey: string; balance: string }) => ({ + privateKey: secretKey, + balance, + })), + forking: mainnetFork, + }, + local: { + url: 'http://127.0.0.1:8545/', + accounts: { + mnemonic: MNEMONIC, + path: MNEMONIC_PATH, + initialIndex: 0, + count: 20, + }, + }, + }, + gasReporter: { + enabled: TRACK_GAS, + }, + spdxLicenseIdentifier: { + overwrite: false, + runOnCompile: false, + }, + etherscan: { + apiKey: BLOCK_EXPLORER_KEY, + }, +}; + +export default config; diff --git a/lens-protocol/core/helper-hardhat-config.ts b/lens-protocol/core/helper-hardhat-config.ts new file mode 100644 index 0000000..fcc3eb6 --- /dev/null +++ b/lens-protocol/core/helper-hardhat-config.ts @@ -0,0 +1,25 @@ +import { + eEthereumNetwork, + ePolygonNetwork, + eXDaiNetwork, + iParamsPerNetwork, +} from './helpers/types'; + +import dotenv from 'dotenv'; +dotenv.config({}); + +const TENDERLY_FORK_ID = process.env.TENDERLY_FORK_ID || ''; + +const GWEI = 1000 * 1000 * 1000; + +export const NETWORKS_RPC_URL: iParamsPerNetwork = { + [eEthereumNetwork.kovan]: process.env.KOVAN_RPC_URL, + [eEthereumNetwork.ropsten]: process.env.ROPSTEN_RPC_URL, + [eEthereumNetwork.main]: process.env.MAINNET_RPC_URL, + [eEthereumNetwork.hardhat]: 'http://localhost:8545', + [eEthereumNetwork.harhatevm]: 'http://localhost:8545', + [eEthereumNetwork.tenderlyMain]: `https://rpc.tenderly.co/fork/${TENDERLY_FORK_ID}`, + [ePolygonNetwork.mumbai]: process.env.MUMBAI_RPC_URL, + [ePolygonNetwork.matic]: process.env.POLYGON_RPC_URL, + [eXDaiNetwork.xdai]: 'https://rpc.xdaichain.com/', +}; diff --git a/lens-protocol/core/helpers/hardhat-constants.ts b/lens-protocol/core/helpers/hardhat-constants.ts new file mode 100644 index 0000000..9237b39 --- /dev/null +++ b/lens-protocol/core/helpers/hardhat-constants.ts @@ -0,0 +1,2 @@ +export const TEST_SNAPSHOT_ID = '0x1'; +export const HARDHATEVM_CHAINID = 31337; diff --git a/lens-protocol/core/helpers/test-wallets.ts b/lens-protocol/core/helpers/test-wallets.ts new file mode 100644 index 0000000..2515a61 --- /dev/null +++ b/lens-protocol/core/helpers/test-wallets.ts @@ -0,0 +1,36 @@ +const balance = '1000000000000000000000000'; + +export const accounts = [ + { + secretKey: '0xc5e8f61d1ab959b397eecc0a37a6517b8e67a0e7cf1f4bce5591f3ed80199122', + balance, + }, + { + secretKey: '0xd49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb', + balance, + }, + { + secretKey: '0x23c601ae397441f3ef6f1075dcb0031ff17fb079837beadaf3c84d96c6f3e569', + balance, + }, + { + secretKey: '0xee9d129c1997549ee09c0757af5939b2483d80ad649a0eda68e8b0357ad11131', + balance, + }, + { + secretKey: '0x87630b2d1de0fbd5044eb6891b3d9d98c34c8d310c852f98550ba774480e47cc', + balance, + }, + { + secretKey: '0x275cc4a2bfd4f612625204a20a2280ab53a6da2d14860c47a9f5affe58ad86d4', + balance, + }, + { + secretKey: '0xaee25d55ce586148a853ca83fdfacaf7bc42d5762c6e7187e6f8e822d8e6a650', + balance, + }, + { + secretKey: '0xa2e0097c961c67ec197b6865d7ecea6caffc68ebeb00e6050368c8f67fc9c588', + balance, + }, +]; diff --git a/lens-protocol/core/helpers/types.ts b/lens-protocol/core/helpers/types.ts new file mode 100644 index 0000000..d28a8b1 --- /dev/null +++ b/lens-protocol/core/helpers/types.ts @@ -0,0 +1,68 @@ +export interface SymbolMap { + [symbol: string]: T; +} + +export type eNetwork = eEthereumNetwork | ePolygonNetwork | eXDaiNetwork; + +export enum eEthereumNetwork { + kovan = 'kovan', + ropsten = 'ropsten', + main = 'main', + hardhat = 'hardhat', + tenderlyMain = 'tenderlyMain', + harhatevm = 'harhatevm', +} + +export enum ePolygonNetwork { + matic = 'matic', + mumbai = 'mumbai', +} + +export enum eXDaiNetwork { + xdai = 'xdai', +} + +export enum EthereumNetworkNames { + kovan = 'kovan', + ropsten = 'ropsten', + main = 'main', + matic = 'matic', + mumbai = 'mumbai', + xdai = 'xdai', +} + +export type tEthereumAddress = string; +export type tStringTokenBigUnits = string; // 1 ETH, or 10e6 USDC or 10e18 DAI +export type tStringTokenSmallUnits = string; // 1 wei, or 1 basic unit of USDC, or 1 basic unit of DAI + +export type iParamsPerNetwork = + | iEthereumParamsPerNetwork + | iPolygonParamsPerNetwork + | iXDaiParamsPerNetwork; + +export interface iParamsPerNetworkAll + extends iEthereumParamsPerNetwork, + iPolygonParamsPerNetwork, + iXDaiParamsPerNetwork {} + +export interface iEthereumParamsPerNetwork { + [eEthereumNetwork.harhatevm]: eNetwork; + [eEthereumNetwork.kovan]: eNetwork; + [eEthereumNetwork.ropsten]: eNetwork; + [eEthereumNetwork.main]: eNetwork; + [eEthereumNetwork.hardhat]: eNetwork; + [eEthereumNetwork.tenderlyMain]: eNetwork; +} + +export interface iPolygonParamsPerNetwork { + [ePolygonNetwork.matic]: T; + [ePolygonNetwork.mumbai]: T; +} + +export interface iXDaiParamsPerNetwork { + [eXDaiNetwork.xdai]: T; +} + +export interface ObjectString { + [key: string]: string; +} diff --git a/lens-protocol/core/helpers/wallet-helpers.ts b/lens-protocol/core/helpers/wallet-helpers.ts new file mode 100644 index 0000000..42a12d0 --- /dev/null +++ b/lens-protocol/core/helpers/wallet-helpers.ts @@ -0,0 +1,20 @@ +import { Wallet, Signer } from 'ethers'; +import { DefenderRelaySigner, DefenderRelayProvider } from 'defender-relay-client/lib/ethers'; +import dotenv from 'dotenv'; + +dotenv.config({ path: '../.env' }); + +const PRIVATE_KEY = process.env.PRIVATE_KEY || ''; +const MNEMONIC = process.env.MNEMONIC || ''; +const DEFENDER_API_KEY = process.env.DEFENDER_API_KEY || ''; +const DEFENDER_SECRET_KEY = process.env.DEFENDER_SECRET_KEY || ''; + +export const getPrivateKeyWallet = (): Signer => new Wallet(PRIVATE_KEY); + +export const getMnemonicWallet = (): Signer => Wallet.fromMnemonic(MNEMONIC); + +export const getDefenderSigner = (): Signer => { + const credentials = { apiKey: DEFENDER_API_KEY, apiSecret: DEFENDER_SECRET_KEY }; + const provider = new DefenderRelayProvider(credentials); + return new DefenderRelaySigner(credentials, provider, { speed: 'fast' }); +}; diff --git a/lens-protocol/core/package-lock.json b/lens-protocol/core/package-lock.json new file mode 100644 index 0000000..a952986 --- /dev/null +++ b/lens-protocol/core/package-lock.json @@ -0,0 +1,40809 @@ +{ + "name": "@aave/lens-protocol", + "version": "1.0.2", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@aave/lens-protocol", + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "@openzeppelin/contracts": "4.5.0" + }, + "devDependencies": { + "@nomiclabs/hardhat-ethers": "2.0.2", + "@nomiclabs/hardhat-etherscan": "2.1.8", + "@typechain/ethers-v5": "8.0.5", + "@typechain/hardhat": "3.0.0", + "@types/chai": "4.2.22", + "@types/mocha": "9.0.0", + "@types/node": "16.11.11", + "@typescript-eslint/eslint-plugin": "5.5.0", + "@typescript-eslint/parser": "5.5.0", + "chai": "4.3.4", + "defender-relay-client": "1.12.1", + "dotenv": "10.0.0", + "eslint": "8.3.0", + "eslint-config-prettier": "8.3.0", + "eslint-plugin-prettier": "4.0.0", + "ethereum-waffle": "3.4.0", + "ethers": "5.5.1", + "hardhat": "2.7.0", + "hardhat-contract-sizer": "2.1.1", + "hardhat-gas-reporter": "1.0.6", + "hardhat-log-remover": "2.0.2", + "hardhat-spdx-license-identifier": "2.0.3", + "husky": "7.0.4", + "prettier": "2.5.0", + "prettier-plugin-solidity": "1.0.0-beta.19", + "solidity-coverage": "0.7.17", + "ts-generator": "0.1.1", + "ts-node": "10.4.0", + "typechain": "6.0.5", + "typescript": "4.5.2" + } + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ensdomains/ens": { + "version": "0.4.5", + "dev": true, + "license": "CC0-1.0", + "dependencies": { + "bluebird": "^3.5.2", + "eth-ens-namehash": "^2.0.8", + "solc": "^0.4.20", + "testrpc": "0.0.1", + "web3-utils": "^1.0.0-beta.31" + } + }, + "node_modules/@ensdomains/ens/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/camelcase": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/cliui": { + "version": "3.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/fs-extra": { + "version": "0.30.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/@ensdomains/ens/node_modules/get-caller-file": { + "version": "1.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/@ensdomains/ens/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/jsonfile": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@ensdomains/ens/node_modules/require-from-string": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/require-main-filename": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/@ensdomains/ens/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@ensdomains/ens/node_modules/solc": { + "version": "0.4.26", + "dev": true, + "license": "MIT", + "dependencies": { + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" + }, + "bin": { + "solcjs": "solcjs" + } + }, + "node_modules/@ensdomains/ens/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/which-module": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@ensdomains/ens/node_modules/wrap-ansi": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/y18n": { + "version": "3.2.2", + "dev": true, + "license": "ISC" + }, + "node_modules/@ensdomains/ens/node_modules/yargs": { + "version": "4.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "node_modules/@ensdomains/ens/node_modules/yargs-parser": { + "version": "2.4.1", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + }, + "node_modules/@ensdomains/resolver": { + "version": "0.2.4", + "dev": true + }, + "node_modules/@eslint/eslintrc": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.0.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@ethereum-waffle/chai": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethereum-waffle/provider": "^3.4.0", + "ethers": "^5.0.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/compiler": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@resolver-engine/imports": "^0.3.3", + "@resolver-engine/imports-fs": "^0.3.3", + "@typechain/ethers-v5": "^2.0.0", + "@types/mkdirp": "^0.5.2", + "@types/node-fetch": "^2.5.5", + "ethers": "^5.0.1", + "mkdirp": "^0.5.1", + "node-fetch": "^2.6.1", + "solc": "^0.6.3", + "ts-generator": "^0.1.1", + "typechain": "^3.0.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/@typechain/ethers-v5": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ethers": "^5.0.2" + }, + "peerDependencies": { + "ethers": "^5.0.0", + "typechain": "^3.0.0" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/jsonfile": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/solc": { + "version": "0.6.12", + "dev": true, + "license": "MIT", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "dev": true, + "license": "MIT", + "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/@ethereum-waffle/compiler/node_modules/ts-essentials": { + "version": "6.0.7", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/typechain": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "command-line-args": "^4.0.7", + "debug": "^4.1.1", + "fs-extra": "^7.0.0", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "ts-essentials": "^6.0.3", + "ts-generator": "^0.1.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + } + }, + "node_modules/@ethereum-waffle/ens": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@ensdomains/ens": "^0.4.4", + "@ensdomains/resolver": "^0.2.4", + "ethers": "^5.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/mock-contract": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.0.1", + "ethers": "^5.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/provider": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethereum-waffle/ens": "^3.3.0", + "ethers": "^5.0.1", + "ganache-core": "^2.13.2", + "patch-package": "^6.2.2", + "postinstall-postinstall": "^2.1.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereumjs/block": { + "version": "3.6.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/tx": "^3.4.0", + "ethereumjs-util": "^7.1.3", + "merkle-patricia-tree": "^4.2.2" + } + }, + "node_modules/@ethereumjs/block/node_modules/@ethereumjs/common": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.3" + } + }, + "node_modules/@ethereumjs/block/node_modules/@ethereumjs/tx": { + "version": "3.4.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^2.6.0", + "ethereumjs-util": "^7.1.3" + } + }, + "node_modules/@ethereumjs/blockchain": { + "version": "5.5.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/block": "^3.6.0", + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/ethash": "^1.1.0", + "debug": "^2.2.0", + "ethereumjs-util": "^7.1.3", + "level-mem": "^5.0.1", + "lru-cache": "^5.1.1", + "semaphore-async-await": "^1.5.1" + } + }, + "node_modules/@ethereumjs/blockchain/node_modules/@ethereumjs/common": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.3" + } + }, + "node_modules/@ethereumjs/blockchain/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@ethereumjs/blockchain/node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@ethereumjs/blockchain/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@ethereumjs/common": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.0" + } + }, + "node_modules/@ethereumjs/common/node_modules/@types/bn.js": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ethereumjs/common/node_modules/bn.js": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@ethereumjs/common/node_modules/ethereumjs-util": { + "version": "7.1.0", + "dev": true, + "license": "MPL-2.0", + "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" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@ethereumjs/ethash": { + "version": "1.1.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/block": "^3.5.0", + "@types/levelup": "^4.3.0", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.1.1", + "miller-rabin": "^4.0.0" + } + }, + "node_modules/@ethereumjs/ethash/node_modules/buffer-xor": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, + "node_modules/@ethereumjs/tx": { + "version": "3.3.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^2.4.0", + "ethereumjs-util": "^7.1.0" + } + }, + "node_modules/@ethereumjs/tx/node_modules/@types/bn.js": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ethereumjs/tx/node_modules/bn.js": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@ethereumjs/tx/node_modules/ethereumjs-util": { + "version": "7.1.0", + "dev": true, + "license": "MPL-2.0", + "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" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@ethereumjs/vm": { + "version": "5.6.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/block": "^3.6.0", + "@ethereumjs/blockchain": "^5.5.0", + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/tx": "^3.4.0", + "async-eventemitter": "^0.2.4", + "core-js-pure": "^3.0.1", + "debug": "^2.2.0", + "ethereumjs-util": "^7.1.3", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "merkle-patricia-tree": "^4.2.2", + "rustbn.js": "~0.2.0" + } + }, + "node_modules/@ethereumjs/vm/node_modules/@ethereumjs/common": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.3" + } + }, + "node_modules/@ethereumjs/vm/node_modules/@ethereumjs/tx": { + "version": "3.4.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^2.6.0", + "ethereumjs-util": "^7.1.3" + } + }, + "node_modules/@ethereumjs/vm/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@ethereumjs/vm/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@ethersproject/abi": { + "version": "5.3.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.3.0", + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/constants": "^5.3.0", + "@ethersproject/hash": "^5.3.0", + "@ethersproject/keccak256": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/strings": "^5.3.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/networks": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/transactions": "^5.3.0", + "@ethersproject/web": "^5.3.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.3.0", + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/keccak256": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/rlp": "^5.3.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.3.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "node_modules/@ethersproject/basex/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/basex/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/basex/node_modules/@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.3.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.3.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.5.0", + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/abi": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "node_modules/@ethersproject/contracts/node_modules/@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.3.0", + "@ethersproject/address": "^5.3.0", + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/keccak256": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/strings": "^5.3.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/basex": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/pbkdf2": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/wordlists": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hdnode": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/pbkdf2": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.3.0", + "js-sha3": "0.5.7" + } + }, + "node_modules/@ethersproject/keccak256/node_modules/js-sha3": { + "version": "0.5.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@ethersproject/logger": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/networks": { + "version": "5.3.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.3.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/sha2": "^5.5.0" + } + }, + "node_modules/@ethersproject/pbkdf2/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/pbkdf2/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/properties": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.3.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/basex": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/random": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/random/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/random/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/rlp": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/sha2/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/sha2/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/solidity/node_modules/@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/solidity/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/solidity/node_modules/@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "node_modules/@ethersproject/solidity/node_modules/@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/solidity/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/solidity/node_modules/@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/constants": "^5.3.0", + "@ethersproject/logger": "^5.3.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.3.0", + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/constants": "^5.3.0", + "@ethersproject/keccak256": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/rlp": "^5.3.0", + "@ethersproject/signing-key": "^5.3.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/units/node_modules/@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/units/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/units/node_modules/@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "node_modules/@ethersproject/units/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/wallet": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/hdnode": "^5.5.0", + "@ethersproject/json-wallets": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/wordlists": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "node_modules/@ethersproject/wallet/node_modules/@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.3.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/strings": "^5.3.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.6.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nomiclabs/hardhat-ethers": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ethers": "^5.0.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan": { + "version": "2.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^5.0.2", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "node-fetch": "^2.6.0", + "semver": "^6.3.0" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.5.0.tgz", + "integrity": "sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA==" + }, + "node_modules/@resolver-engine/core": { + "version": "0.3.3", + "dev": true, + "license": "LGPL-3.0-or-later", + "dependencies": { + "debug": "^3.1.0", + "is-url": "^1.2.4", + "request": "^2.85.0" + } + }, + "node_modules/@resolver-engine/core/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@resolver-engine/fs": { + "version": "0.3.3", + "dev": true, + "license": "LGPL-3.0-or-later", + "dependencies": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0" + } + }, + "node_modules/@resolver-engine/fs/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@resolver-engine/imports": { + "version": "0.3.3", + "dev": true, + "license": "LGPL-3.0-or-later", + "dependencies": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0", + "hosted-git-info": "^2.6.0", + "path-browserify": "^1.0.0", + "url": "^0.11.0" + } + }, + "node_modules/@resolver-engine/imports-fs": { + "version": "0.3.3", + "dev": true, + "license": "LGPL-3.0-or-later", + "dependencies": { + "@resolver-engine/fs": "^0.3.3", + "@resolver-engine/imports": "^0.3.3", + "debug": "^3.1.0" + } + }, + "node_modules/@resolver-engine/imports-fs/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@resolver-engine/imports/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "dev": true, + "license": "BSD-3-Clause", + "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", + "dev": true, + "license": "BSD-3-Clause", + "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", + "dev": true, + "license": "BSD-3-Clause", + "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", + "dev": true, + "license": "BSD-3-Clause", + "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", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@solidity-parser/parser": { + "version": "0.14.0", + "dev": true, + "license": "MIT", + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@truffle/error": { + "version": "0.0.14", + "dev": true, + "license": "MIT" + }, + "node_modules/@truffle/interface-adapter": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^5.1.3", + "ethers": "^4.0.32", + "web3": "1.5.3" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/bn.js": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@truffle/interface-adapter/node_modules/ethers": { + "version": "4.0.49", + "dev": true, + "license": "MIT", + "dependencies": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/ethers/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@truffle/interface-adapter/node_modules/hash.js": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/js-sha3": { + "version": "0.5.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@truffle/interface-adapter/node_modules/scrypt-js": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@truffle/interface-adapter/node_modules/setimmediate": { + "version": "1.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@truffle/interface-adapter/node_modules/uuid": { + "version": "2.0.1", + "dev": true + }, + "node_modules/@truffle/provider": { + "version": "0.2.41", + "dev": true, + "license": "MIT", + "dependencies": { + "@truffle/error": "^0.0.14", + "@truffle/interface-adapter": "^0.5.7", + "web3": "1.5.3" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@typechain/ethers-v5": { + "version": "8.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + }, + "peerDependencies": { + "@ethersproject/abi": "^5.0.0", + "@ethersproject/bytes": "^5.0.0", + "@ethersproject/providers": "^5.0.0", + "ethers": "^5.1.3", + "typechain": "^6.0.4", + "typescript": ">=4.0.0" + } + }, + "node_modules/@typechain/ethers-v5/node_modules/ts-essentials": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/@typechain/hardhat": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fs-extra": "^9.1.0" + }, + "peerDependencies": { + "hardhat": "^2.0.10", + "lodash": "^4.17.15", + "typechain": "^6.0.0" + } + }, + "node_modules/@typechain/hardhat/node_modules/fs-extra": { + "version": "9.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typechain/hardhat/node_modules/jsonfile": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@typechain/hardhat/node_modules/universalify": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@types/abstract-leveldown": { + "version": "5.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/bn.js": { + "version": "4.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.2.22", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/level-errors": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/levelup": { + "version": "4.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/abstract-leveldown": "*", + "@types/level-errors": "*", + "@types/node": "*" + } + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mkdirp": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "9.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "16.11.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node-fetch": { + "version": "2.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/resolve": { + "version": "0.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/experimental-utils": "5.5.0", + "@typescript-eslint/scope-manager": "5.5.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": { + "version": "4.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.5.0", + "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/typescript-estree": "5.5.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.5.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "5.5.0", + "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/typescript-estree": "5.5.0", + "debug": "^4.3.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/visitor-keys": "5.5.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.5.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/visitor-keys": "5.5.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.5.0", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abbrev": { + "version": "1.0.9", + "dev": true, + "license": "ISC" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-leveldown": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/accepts": { + "version": "1.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.6.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amazon-cognito-identity-js": { + "version": "4.6.3", + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "dependencies": { + "buffer": "4.9.2", + "crypto-js": "^4.0.0", + "fast-base64-decode": "^1.0.0", + "isomorphic-unfetch": "^3.0.0", + "js-cookie": "^2.2.1" + } + }, + "node_modules/amazon-cognito-identity-js/node_modules/buffer": { + "version": "4.9.2", + "dev": true, + "license": "MIT", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/amdefine": { + "version": "1.0.1", + "dev": true, + "license": "BSD-3-Clause OR MIT", + "optional": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/anymatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-back": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/asn1": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/async": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-eventemitter": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^2.4.0" + } + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "0.19.2", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "1.5.10" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "license": "Unlicense" + }, + "node_modules/bech32": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/bignumber.js": { + "version": "9.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bip66": { + "version": "1.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/blakejs": { + "version": "1.1.0", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/bluebird": { + "version": "3.7.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.19.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/http-errors": { + "version": "1.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/body-parser/node_modules/raw-body": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-rsa/node_modules/bn.js": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/bn.js": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/bs58": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/bufferutil": { + "version": "4.0.4", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/bytes": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/cbor": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.1", + "nofilter": "^1.0.4" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/chai": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ci-info": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cids": { + "version": "0.7.5", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/class-is": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-table3": { + "version": "0.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "5.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/colors": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "dev": true, + "license": "MIT" + }, + "node_modules/command-line-args": { + "version": "4.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^2.0.0", + "find-replace": "^1.0.3", + "typical": "^2.6.1" + }, + "bin": { + "command-line-args": "bin/cli.js" + } + }, + "node_modules/commander": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/content-hash": { + "version": "2.5.2", + "dev": true, + "license": "ISC", + "dependencies": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/cookiejar": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js-pure": { + "version": "3.19.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/crc-32": { + "version": "1.2.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.1.0" + }, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/crypto-js": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/d": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/death": { + "version": "1.1.0", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/deep-is": { + "version": "0.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/defender-base-client": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "amazon-cognito-identity-js": "^4.3.3", + "axios": "^0.19.2", + "lodash": "^4.17.19", + "node-fetch": "^2.6.0" + } + }, + "node_modules/defender-relay-client": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "amazon-cognito-identity-js": "^4.3.3", + "axios": "^0.19.2", + "defender-base-client": "^1.12.1", + "lodash": "^4.17.19", + "node-fetch": "^2.6.0" + }, + "peerDependencies": { + "@ethersproject/abstract-provider": "^5.0.2", + "@ethersproject/abstract-signer": "^5.0.2", + "@ethersproject/providers": "^5.0.5", + "web3-core": "^1.3.4", + "web3-core-helpers": "^1.3.4" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/deferred-leveldown": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deferred-leveldown/node_modules/abstract-leveldown": { + "version": "6.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-port": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/diff": { + "version": "3.5.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "dev": true + }, + "node_modules/dotenv": { + "version": "10.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } + }, + "node_modules/drbg.js": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/elliptic": { + "version": "6.5.4", + "dev": true, + "license": "MIT", + "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": "7.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding-down": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.19.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/is-callable": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/is-string": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/object-inspect": { + "version": "1.11.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/object.assign": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.53", + "dev": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.8.1", + "dev": true, + "license": "BSD-2-Clause", + "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", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "1.9.3", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.2.0", + "dev": true, + "optional": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint/eslintrc": "^1.0.4", + "@humanwhocodes/config-array": "^0.6.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.1.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "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": "8.3.0", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/glob-parent/node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/espree": { + "version": "9.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.6.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eth-ens-namehash": { + "version": "2.0.8", + "dev": true, + "license": "ISC", + "dependencies": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "node_modules/eth-ens-namehash/node_modules/js-sha3": { + "version": "0.5.7", + "dev": true, + "license": "MIT" + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.23", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.0.0-beta.146", + "@solidity-parser/parser": "^0.14.0", + "cli-table3": "^0.5.0", + "colors": "^1.1.2", + "ethereumjs-util": "6.2.0", + "ethers": "^4.0.40", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^7.1.1", + "req-cwd": "^2.0.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "peerDependencies": { + "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } + } + }, + "node_modules/eth-gas-reporter/node_modules/cli-table3": { + "version": "0.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethereumjs-util": { + "version": "6.2.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "0.1.6", + "keccak": "^2.0.0", + "rlp": "^2.2.3", + "secp256k1": "^3.0.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethers": { + "version": "4.0.49", + "dev": true, + "license": "MIT", + "dependencies": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/hash.js": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/js-sha3": { + "version": "0.5.7", + "dev": true, + "license": "MIT" + }, + "node_modules/eth-gas-reporter/node_modules/keccak": { + "version": "2.1.0", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "inherits": "^2.0.4", + "nan": "^2.14.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=5.12.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/scrypt-js": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/eth-gas-reporter/node_modules/secp256k1": { + "version": "3.8.0", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.5.2", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/setimmediate": { + "version": "1.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/eth-gas-reporter/node_modules/uuid": { + "version": "2.0.1", + "dev": true + }, + "node_modules/eth-lib": { + "version": "0.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/eth-sig-util": { + "version": "2.5.4", + "dev": true, + "license": "ISC", + "dependencies": { + "ethereumjs-abi": "0.6.8", + "ethereumjs-util": "^5.1.1", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.0" + } + }, + "node_modules/eth-sig-util/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.0.9", + "dev": true, + "license": "MIT", + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereum-waffle": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethereum-waffle/chai": "^3.4.0", + "@ethereum-waffle/compiler": "^3.4.0", + "@ethereum-waffle/mock-contract": "^3.3.0", + "@ethereum-waffle/provider": "^3.4.0", + "ethers": "^5.0.1" + }, + "bin": { + "waffle": "bin/waffle" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "git+ssh://git@github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.3", + "dev": true, + "license": "MPL-2.0", + "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/@types/bn.js": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-util/node_modules/bn.js": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ethers": { + "version": "5.5.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.5.0", + "@ethersproject/abstract-provider": "5.5.1", + "@ethersproject/abstract-signer": "5.5.0", + "@ethersproject/address": "5.5.0", + "@ethersproject/base64": "5.5.0", + "@ethersproject/basex": "5.5.0", + "@ethersproject/bignumber": "5.5.0", + "@ethersproject/bytes": "5.5.0", + "@ethersproject/constants": "5.5.0", + "@ethersproject/contracts": "5.5.0", + "@ethersproject/hash": "5.5.0", + "@ethersproject/hdnode": "5.5.0", + "@ethersproject/json-wallets": "5.5.0", + "@ethersproject/keccak256": "5.5.0", + "@ethersproject/logger": "5.5.0", + "@ethersproject/networks": "5.5.0", + "@ethersproject/pbkdf2": "5.5.0", + "@ethersproject/properties": "5.5.0", + "@ethersproject/providers": "5.5.0", + "@ethersproject/random": "5.5.0", + "@ethersproject/rlp": "5.5.0", + "@ethersproject/sha2": "5.5.0", + "@ethersproject/signing-key": "5.5.0", + "@ethersproject/solidity": "5.5.0", + "@ethersproject/strings": "5.5.0", + "@ethersproject/transactions": "5.5.0", + "@ethersproject/units": "5.5.0", + "@ethersproject/wallet": "5.5.0", + "@ethersproject/web": "5.5.0", + "@ethersproject/wordlists": "5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/abi": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/ethers/node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/logger": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/ethers/node_modules/@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/ethers/node_modules/@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "MIT" + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/exit-on-epipe": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/express": { + "version": "4.17.1", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/qs": { + "version": "6.7.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ext": { + "version": "1.6.0", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.5.0" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.5.0", + "dev": true, + "license": "ISC" + }, + "node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-base64-decode": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.11.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/find-replace": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^1.0.4", + "test-value": "^2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-replace/node_modules/array-back": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "micromatch": "^4.0.2" + } + }, + "node_modules/flat": { + "version": "4.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "is-buffer": "~2.0.3" + }, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.2.4", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "=3.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/follow-redirects/node_modules/debug": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/follow-redirects/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/foreach": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-cli": { + "version": "6.12.2", + "bundleDependencies": [ + "source-map-support", + "yargs", + "ethereumjs-util" + ], + "dev": true, + "license": "MIT", + "dependencies": { + "ethereumjs-util": "6.2.1", + "source-map-support": "0.5.12", + "yargs": "13.2.4" + }, + "bin": { + "ganache-cli": "cli.js" + } + }, + "node_modules/ganache-cli/node_modules/@types/bn.js": { + "version": "4.11.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-cli/node_modules/@types/node": { + "version": "14.11.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/@types/pbkdf2": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-cli/node_modules/@types/secp256k1": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-cli/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/base-x": { + "version": "3.0.8", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-cli/node_modules/blakejs": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/ganache-cli/node_modules/bn.js": { + "version": "4.11.9", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/brorand": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/browserify-aes": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-cli/node_modules/bs58": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/ganache-cli/node_modules/bs58check": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-cli/node_modules/buffer-from": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/cipher-base": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-cli/node_modules/cliui": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/ganache-cli/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ganache-cli/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/create-hash": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/ganache-cli/node_modules/create-hmac": { + "version": "1.1.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/ganache-cli/node_modules/cross-spawn": { + "version": "6.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/ganache-cli/node_modules/decamelize": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/elliptic": { + "version": "6.5.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "node_modules/ganache-cli/node_modules/emoji-regex": { + "version": "7.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/ganache-cli/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ganache-cli/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-cli/node_modules/ethjs-util": { + "version": "0.1.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-cli/node_modules/evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-cli/node_modules/execa": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/find-up": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/ganache-cli/node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/hash-base": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/hash.js": { + "version": "1.1.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/ganache-cli/node_modules/hmac-drbg": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ganache-cli/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/invert-kv": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/is-hex-prefixed": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-cli/node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/keccak": { + "version": "3.0.1", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-cli/node_modules/lcid": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "invert-kv": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/locate-path": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/map-age-cleaner": { + "version": "0.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/md5.js": { + "version": "1.3.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-cli/node_modules/mem": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/nice-try": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/node-addon-api": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/node-gyp-build": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/ganache-cli/node_modules/npm-run-path": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/ganache-cli/node_modules/os-locale": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/p-defer": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/p-finally": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/p-is-promise": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ganache-cli/node_modules/p-locate": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/path-exists": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/pbkdf2": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/ganache-cli/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/ganache-cli/node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/ganache-cli/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-cli/node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/require-main-filename": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/ripemd160": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/ganache-cli/node_modules/rlp": { + "version": "2.2.6", + "dev": true, + "inBundle": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.1" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/ganache-cli/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/scrypt-js": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/secp256k1": { + "version": "4.0.2", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-cli/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-cli/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/setimmediate": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/sha.js": { + "version": "2.4.11", + "dev": true, + "inBundle": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/ganache-cli/node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/signal-exit": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/source-map-support": { + "version": "0.5.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/ganache-cli/node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ganache-cli/node_modules/string-width": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/strip-eof": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/strip-hex-prefix": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-cli/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/which": { + "version": "1.3.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/ganache-cli/node_modules/which-module": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/wrap-ansi": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/y18n": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/yargs": { + "version": "13.2.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "node_modules/ganache-cli/node_modules/yargs-parser": { + "version": "13.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/ganache-core": { + "version": "2.13.2", + "bundleDependencies": [ + "keccak" + ], + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "3.0.0", + "async": "2.6.2", + "bip39": "2.5.0", + "cachedown": "1.0.0", + "clone": "2.1.2", + "debug": "3.2.6", + "encoding-down": "5.0.4", + "eth-sig-util": "3.0.0", + "ethereumjs-abi": "0.6.8", + "ethereumjs-account": "3.0.0", + "ethereumjs-block": "2.2.2", + "ethereumjs-common": "1.5.0", + "ethereumjs-tx": "2.1.2", + "ethereumjs-util": "6.2.1", + "ethereumjs-vm": "4.2.0", + "heap": "0.2.6", + "keccak": "3.0.1", + "level-sublevel": "6.6.4", + "levelup": "3.1.1", + "lodash": "4.17.20", + "lru-cache": "5.1.1", + "merkle-patricia-tree": "3.0.0", + "patch-package": "6.2.2", + "seedrandom": "3.0.1", + "source-map-support": "0.5.12", + "tmp": "0.1.0", + "web3-provider-engine": "14.2.1", + "websocket": "1.0.32" + }, + "engines": { + "node": ">=8.9.0" + }, + "optionalDependencies": { + "ethereumjs-wallet": "0.6.5", + "web3": "1.2.11" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/abi": { + "version": "5.0.0-beta.153", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/address": ">=5.0.0-beta.128", + "@ethersproject/bignumber": ">=5.0.0-beta.130", + "@ethersproject/bytes": ">=5.0.0-beta.129", + "@ethersproject/constants": ">=5.0.0-beta.128", + "@ethersproject/hash": ">=5.0.0-beta.128", + "@ethersproject/keccak256": ">=5.0.0-beta.127", + "@ethersproject/logger": ">=5.0.0-beta.129", + "@ethersproject/properties": ">=5.0.0-beta.131", + "@ethersproject/strings": ">=5.0.0-beta.130" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/abstract-provider": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/networks": "^5.0.7", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/transactions": "^5.0.9", + "@ethersproject/web": "^5.0.12" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/abstract-signer": { + "version": "5.0.10", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.0.8", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/address": { + "version": "5.0.9", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/rlp": "^5.0.7" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/base64": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/bignumber": { + "version": "5.0.13", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "bn.js": "^4.4.0" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/bytes": { + "version": "5.0.9", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/constants": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.0.13" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/hash": { + "version": "5.0.10", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.0.10", + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/keccak256": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "js-sha3": "0.5.7" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/logger": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/@ethersproject/networks": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/properties": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/rlp": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/signing-key": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "elliptic": "6.5.3" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/strings": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/transactions": { + "version": "5.0.9", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/rlp": "^5.0.7", + "@ethersproject/signing-key": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/web": { + "version": "5.0.12", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/base64": "^5.0.7", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@sindresorhus/is": { + "version": "0.14.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/@types/bn.js": { + "version": "4.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-core/node_modules/@types/node": { + "version": "14.14.20", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/@types/pbkdf2": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-core/node_modules/@types/secp256k1": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-core/node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/ganache-core/node_modules/abstract-leveldown": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/accepts": { + "version": "1.3.7", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/aes-js": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ganache-core/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/arr-diff": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/arr-flatten": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/arr-union": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/array-unique": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/asn1": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/ganache-core/node_modules/asn1.js": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ganache-core/node_modules/assert-plus": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ganache-core/node_modules/assign-symbols": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/async": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.11" + } + }, + "node_modules/ganache-core/node_modules/async-eventemitter": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^2.4.0" + } + }, + "node_modules/ganache-core/node_modules/async-limiter": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/atob": { + "version": "2.1.2", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/ganache-core/node_modules/aws-sign2": { + "version": "0.7.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/aws4": { + "version": "1.11.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-code-frame": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ganache-core/node_modules/babel-core": { + "version": "6.26.3", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": { + "version": "0.5.1", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-generator": { + "version": "6.26.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-call-delegate": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-define-map": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-function-name": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-regex": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-replace-supers": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helpers": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-messages": { + "version": "6.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-transform": "^0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-preset-env": { + "version": "1.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/babel-register": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": { + "version": "0.4.18", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "^0.5.6" + } + }, + "node_modules/ganache-core/node_modules/babel-runtime": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/ganache-core/node_modules/babel-template": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": { + "version": "9.18.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-types": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "node_modules/ganache-core/node_modules/babel-types/node_modules/to-fast-properties": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babelify": { + "version": "7.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/babylon": { + "version": "6.18.0", + "dev": true, + "license": "MIT", + "bin": { + "babylon": "bin/babylon.js" + } + }, + "node_modules/ganache-core/node_modules/backoff": { + "version": "2.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/balanced-match": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/base": { + "version": "0.11.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/base-x": { + "version": "3.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-core/node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "license": "Unlicense" + }, + "node_modules/ganache-core/node_modules/bignumber.js": { + "version": "9.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/bip39": { + "version": "2.5.0", + "dev": true, + "license": "ISC", + "dependencies": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "node_modules/ganache-core/node_modules/blakejs": { + "version": "1.1.0", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/ganache-core/node_modules/bluebird": { + "version": "3.7.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/bn.js": { + "version": "4.11.9", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/body-parser": { + "version": "1.19.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/ganache-core/node_modules/brorand": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/browserify-aes": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-core/node_modules/browserify-cipher": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/browserify-des": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/browserify-rsa": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/ganache-core/node_modules/browserify-rsa/node_modules/bn.js": { + "version": "5.1.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/browserify-sign": { + "version": "4.2.1", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": { + "version": "5.1.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/browserslist": { + "version": "3.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/ganache-core/node_modules/bs58": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/ganache-core/node_modules/bs58check": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/ganache-core/node_modules/buffer-from": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/bufferutil": { + "version": "4.0.3", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/ganache-core/node_modules/bytes": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/bytewise": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "node_modules/ganache-core/node_modules/bytewise-core": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "typewise-core": "^1.2" + } + }, + "node_modules/ganache-core/node_modules/cache-base": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/cacheable-request": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ganache-core/node_modules/cachedown": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "^2.4.1", + "lru-cache": "^3.2.0" + } + }, + "node_modules/ganache-core/node_modules/cachedown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": { + "version": "3.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/call-bind": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/caniuse-lite": { + "version": "1.0.30001174", + "dev": true, + "license": "CC-BY-4.0" + }, + "node_modules/ganache-core/node_modules/caseless": { + "version": "0.12.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/ganache-core/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/checkpoint-store": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "functional-red-black-tree": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/chownr": { + "version": "1.1.4", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ganache-core/node_modules/ci-info": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/cids": { + "version": "0.7.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/ganache-core/node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/cipher-base": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-core/node_modules/class-is": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/class-utils": { + "version": "0.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/clone": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ganache-core/node_modules/clone-response": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/collection-visit": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ganache-core/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/component-emitter": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/concat-stream": { + "version": "1.6.2", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/ganache-core/node_modules/content-disposition": { + "version": "0.5.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/content-hash": { + "version": "2.5.2", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "node_modules/ganache-core/node_modules/content-type": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/convert-source-map": { + "version": "1.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/cookie": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/cookiejar": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/copy-descriptor": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/core-js": { + "version": "2.6.12", + "dev": true, + "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/core-js-pure": { + "version": "3.8.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/ganache-core/node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/cors": { + "version": "2.8.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ganache-core/node_modules/create-ecdh": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/ganache-core/node_modules/create-hash": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/ganache-core/node_modules/create-hmac": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/ganache-core/node_modules/cross-fetch": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" + } + }, + "node_modules/ganache-core/node_modules/crypto-browserify": { + "version": "3.12.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/d": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/dashdash": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ganache-core/node_modules/debug": { + "version": "3.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/ganache-core/node_modules/decode-uri-component": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ganache-core/node_modules/decompress-response": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/deep-equal": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/defer-to-connect": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/deferred-leveldown": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~5.0.0", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/define-properties": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ganache-core/node_modules/define-property": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/defined": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ganache-core/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/des.js": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/destroy": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/detect-indent": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/diffie-hellman": { + "version": "5.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/dom-walk": { + "version": "0.1.2", + "dev": true + }, + "node_modules/ganache-core/node_modules/dotignore": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.4" + }, + "bin": { + "ignored": "bin/ignored" + } + }, + "node_modules/ganache-core/node_modules/duplexer3": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/ganache-core/node_modules/ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ganache-core/node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/electron-to-chromium": { + "version": "1.3.636", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/elliptic": { + "version": "6.5.3", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/ganache-core/node_modules/encoding-down": { + "version": "5.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "^5.0.0", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/encoding-down/node_modules/abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/ganache-core/node_modules/errno": { + "version": "0.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/ganache-core/node_modules/es-abstract": { + "version": "1.18.0-next.1", + "dev": true, + "license": "MIT", + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/es-to-primitive": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/es5-ext": { + "version": "0.10.53", + "dev": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/ganache-core/node_modules/es6-iterator": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/ganache-core/node_modules/es6-symbol": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/ganache-core/node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ganache-core/node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/etag": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eth-query": "^2.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.3", + "ethjs-util": "^0.1.3", + "json-rpc-engine": "^3.6.0", + "pify": "^2.3.0", + "tape": "^4.6.3" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/eth-ens-namehash": { + "version": "2.0.8", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-infura": { + "version": "3.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-fetch": "^2.1.1", + "eth-json-rpc-middleware": "^1.5.0", + "json-rpc-engine": "^3.4.0", + "json-rpc-error": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": { + "version": "1.6.0", + "dev": true, + "license": "ISC", + "dependencies": { + "async": "^2.5.0", + "eth-query": "^2.1.2", + "eth-tx-summary": "^3.1.2", + "ethereumjs-block": "^1.6.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.2", + "ethereumjs-vm": "^2.1.0", + "fetch-ponyfill": "^4.0.0", + "json-rpc-engine": "^3.6.0", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "tape": "^4.6.3" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-lib": { + "version": "0.1.29", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-query": { + "version": "2.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "json-rpc-random-id": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "buffer": "^5.2.1", + "elliptic": "^6.4.0", + "ethereumjs-abi": "0.6.5", + "ethereumjs-util": "^5.1.1", + "tweetnacl": "^1.0.0", + "tweetnacl-util": "^0.15.0" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": { + "version": "0.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "4.5.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary": { + "version": "3.2.4", + "dev": true, + "license": "ISC", + "dependencies": { + "async": "^2.1.2", + "clone": "^2.0.0", + "concat-stream": "^1.5.1", + "end-of-stream": "^1.1.0", + "eth-query": "^2.0.2", + "ethereumjs-block": "^1.4.1", + "ethereumjs-tx": "^1.1.1", + "ethereumjs-util": "^5.0.1", + "ethereumjs-vm": "^2.6.0", + "through2": "^2.0.3" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethashjs": { + "version": "0.0.8", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.0.2", + "miller-rabin": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": { + "version": "5.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": { + "version": "7.0.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereum-bloom-filters": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": { + "version": "0.8.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ethereum-common": { + "version": "0.0.18", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-account": { + "version": "3.0.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-util": "^6.0.0", + "rlp": "^2.2.1", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-blockchain": { + "version": "4.0.4", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.6.1", + "ethashjs": "~0.0.7", + "ethereumjs-block": "~2.2.2", + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.1.0", + "flow-stoplight": "^1.0.0", + "level-mem": "^3.0.1", + "lru-cache": "^5.1.1", + "rlp": "^2.2.2", + "semaphore": "^1.1.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-common": { + "version": "1.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm": { + "version": "4.2.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "core-js-pure": "^3.0.1", + "ethereumjs-account": "^3.0.0", + "ethereumjs-block": "^2.2.2", + "ethereumjs-blockchain": "^4.0.3", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.2", + "ethereumjs-util": "^6.2.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1", + "util.promisify": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-wallet": { + "version": "0.6.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "aes-js": "^3.1.1", + "bs58check": "^2.1.2", + "ethereum-cryptography": "^0.1.3", + "ethereumjs-util": "^6.0.0", + "randombytes": "^2.0.6", + "safe-buffer": "^5.1.2", + "scryptsy": "^1.2.1", + "utf8": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "node_modules/ganache-core/node_modules/ethjs-unit": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ethjs-util": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/eventemitter3": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/events": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/ganache-core/node_modules/evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/express": { + "version": "4.17.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/ganache-core/node_modules/express/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/express/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/express/node_modules/qs": { + "version": "6.7.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/express/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ext": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/ext/node_modules/type": { + "version": "2.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/extend-shallow": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extsprintf": { + "version": "1.3.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/fake-merkle-patricia-tree": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "checkpoint-store": "^1.1.0" + } + }, + "node_modules/ganache-core/node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/fetch-ponyfill": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "~1.7.1" + } + }, + "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/finalhandler": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root": { + "version": "1.2.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "fs-extra": "^4.0.3", + "micromatch": "^3.1.4" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces": { + "version": "2.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fs-extra": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/micromatch": { + "version": "3.1.10", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/to-regex-range": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/flow-stoplight": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/for-each": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/ganache-core/node_modules/for-in": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/forever-agent": { + "version": "0.6.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/form-data": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/ganache-core/node_modules/forwarded": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/fragment-cache": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/fs-extra": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/ganache-core/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/functional-red-black-tree": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/get-intrinsic": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ganache-core/node_modules/get-value": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/getpass": { + "version": "0.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/glob": { + "version": "7.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/global": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/ganache-core/node_modules/got": { + "version": "9.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ganache-core/node_modules/got/node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/graceful-fs": { + "version": "4.2.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/har-schema": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/har-validator": { + "version": "5.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/has": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ganache-core/node_modules/has-ansi": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/has-symbol-support-x": { + "version": "1.4.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/has-symbols": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/has-value": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/hash-base": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/hash.js": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/heap": { + "version": "0.2.6", + "dev": true + }, + "node_modules/ganache-core/node_modules/hmac-drbg": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/home-or-tmp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/http-cache-semantics": { + "version": "4.1.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true + }, + "node_modules/ganache-core/node_modules/http-errors": { + "version": "1.7.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ganache-core/node_modules/http-https": { + "version": "1.0.0", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ganache-core/node_modules/http-signature": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/ganache-core/node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/idna-uts46-hx": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "punycode": "2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ganache-core/node_modules/idna-uts46-hx/node_modules/punycode": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ganache-core/node_modules/immediate": { + "version": "3.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/ganache-core/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/invariant": { + "version": "2.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/ipaddr.js": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ganache-core/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-arguments": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-callable": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-ci": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/ganache-core/node_modules/is-data-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-date-object": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-descriptor": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-extendable": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-finite": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ganache-core/node_modules/is-fn": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-function": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/is-hex-prefixed": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/is-negative-zero": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-object": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-plain-obj": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-regex": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-retry-allowed": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-symbol": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/is-windows": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/isobject": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/isstream": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/isurl": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ganache-core/node_modules/js-sha3": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/jsbn": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/json-buffer": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/json-rpc-engine": { + "version": "3.8.0", + "dev": true, + "license": "ISC", + "dependencies": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/json-rpc-error": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/ganache-core/node_modules/json-rpc-random-id": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/json-schema": { + "version": "0.2.3", + "dev": true + }, + "node_modules/ganache-core/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/json-stable-stringify": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonify": "~0.0.0" + } + }, + "node_modules/ganache-core/node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/jsonfile": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/ganache-core/node_modules/jsonify": { + "version": "0.0.0", + "dev": true, + "license": "Public Domain" + }, + "node_modules/ganache-core/node_modules/jsprim": { + "version": "1.4.1", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/ganache-core/node_modules/keccak": { + "version": "3.0.1", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-core/node_modules/keyv": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/ganache-core/node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/klaw-sync": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/ganache-core/node_modules/level-codec": { + "version": "9.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-errors": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-iterator-stream": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.5", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/level-mem": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "level-packager": "~4.0.0", + "memdown": "~3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/memdown": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~5.0.0", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/level-packager": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "encoding-down": "~5.0.0", + "levelup": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-post": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ltgt": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/level-sublevel": { + "version": "6.6.4", + "dev": true, + "license": "MIT", + "dependencies": { + "bytewise": "~1.1.0", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "level-iterator-stream": "^2.0.3", + "ltgt": "~2.1.1", + "pull-defer": "^0.2.2", + "pull-level": "^2.0.3", + "pull-stream": "^3.6.8", + "typewiselite": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/level-ws": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.8", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/levelup": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~4.0.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~3.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/levelup/node_modules/level-iterator-stream": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/lodash": { + "version": "4.17.20", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/looper": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/loose-envify": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/ganache-core/node_modules/lowercase-keys": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ganache-core/node_modules/ltgt": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/map-cache": { + "version": "0.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/map-visit": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/md5.js": { + "version": "1.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/media-typer": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/merge-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/merkle-patricia-tree": { + "version": "3.0.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.6.1", + "ethereumjs-util": "^5.2.0", + "level-mem": "^3.0.1", + "level-ws": "^1.0.0", + "readable-stream": "^3.0.6", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/miller-rabin": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/ganache-core/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/mime-db": { + "version": "1.45.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/mime-types": { + "version": "2.1.28", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.45.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/mimic-response": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/min-document": { + "version": "2.19.0", + "dev": true, + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/minimist": { + "version": "1.2.5", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/minizlib": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/ganache-core/node_modules/minizlib/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/ganache-core/node_modules/mixin-deep": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ganache-core/node_modules/mkdirp-promise": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "mkdirp": "*" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/mock-fs": { + "version": "4.13.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/multibase": { + "version": "0.6.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/ganache-core/node_modules/multicodec": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "varint": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/multihashes": { + "version": "0.4.21", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/ganache-core/node_modules/nano-json-stream-parser": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/nanomatch": { + "version": "1.2.13", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/negotiator": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/next-tick": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/nice-try": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/node-addon-api": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/node-fetch": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/ganache-core/node_modules/node-gyp-build": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/ganache-core/node_modules/normalize-url": { + "version": "4.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ganache-core/node_modules/number-to-bn": { + "version": "1.7.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/oauth-sign": { + "version": "0.9.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-inspect": { + "version": "1.9.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object-is": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ganache-core/node_modules/object-visit": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object.assign": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object.getownpropertydescriptors": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object.pick": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/oboe": { + "version": "2.1.4", + "dev": true, + "license": "BSD", + "optional": true, + "dependencies": { + "http-https": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/on-finished": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/ganache-core/node_modules/os-homedir": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/os-tmpdir": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/p-cancelable": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/p-timeout": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/p-timeout/node_modules/p-finally": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/parse-asn1": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/parse-headers": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/pascalcase": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package": { + "version": "6.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^1.2.1", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "npm": ">5" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/cross-spawn": { + "version": "6.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/tmp": { + "version": "0.0.33", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/which": { + "version": "1.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/ganache-core/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/path-parse": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/path-to-regexp": { + "version": "0.1.7", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/pbkdf2": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/ganache-core/node_modules/performance-now": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/posix-character-classes": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/precond": { + "version": "0.2.3", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/prepend-http": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/private": { + "version": "0.1.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/process": { + "version": "0.11.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/ganache-core/node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/promise-to-callback": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-fn": "^1.0.0", + "set-immediate-shim": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/proxy-addr": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ganache-core/node_modules/prr": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pseudomap": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/psl": { + "version": "1.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/public-encrypt": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/pull-cat": { + "version": "1.1.11", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pull-defer": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pull-level": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "level-post": "^1.0.7", + "pull-cat": "^1.1.9", + "pull-live": "^1.0.1", + "pull-pushable": "^2.0.0", + "pull-stream": "^3.4.0", + "pull-window": "^2.1.4", + "stream-to-pull-stream": "^1.7.1" + } + }, + "node_modules/ganache-core/node_modules/pull-live": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "pull-cat": "^1.1.9", + "pull-stream": "^3.4.0" + } + }, + "node_modules/ganache-core/node_modules/pull-pushable": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pull-stream": { + "version": "3.6.14", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pull-window": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "looper": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/ganache-core/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/qs": { + "version": "6.5.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/query-string": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/ganache-core/node_modules/randomfill": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/ganache-core/node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/raw-body": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/readable-stream": { + "version": "2.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/ganache-core/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/regenerate": { + "version": "1.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/regenerator-runtime": { + "version": "0.11.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/regenerator-transform": { + "version": "0.10.1", + "dev": true, + "license": "BSD", + "dependencies": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "node_modules/ganache-core/node_modules/regex-not": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/regexp.prototype.flags": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/regexp.prototype.flags/node_modules/es-abstract": { + "version": "1.17.7", + "dev": true, + "license": "MIT", + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/regexpu-core": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "node_modules/ganache-core/node_modules/regjsgen": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/regjsparser": { + "version": "0.1.5", + "dev": true, + "license": "BSD", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/ganache-core/node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/ganache-core/node_modules/repeat-element": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/repeat-string": { + "version": "1.6.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ganache-core/node_modules/repeating": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/request": { + "version": "2.88.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/resolve-url": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/responselike": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/resumer": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "~2.3.4" + } + }, + "node_modules/ganache-core/node_modules/ret": { + "version": "0.1.15", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/ganache-core/node_modules/rimraf": { + "version": "2.6.3", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ganache-core/node_modules/ripemd160": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/ganache-core/node_modules/rlp": { + "version": "2.2.6", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.1" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/ganache-core/node_modules/rustbn.js": { + "version": "0.2.0", + "dev": true, + "license": "(MIT OR Apache-2.0)" + }, + "node_modules/ganache-core/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/safe-event-emitter": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "events": "^3.0.0" + } + }, + "node_modules/ganache-core/node_modules/safe-regex": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/ganache-core/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/scrypt-js": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/scryptsy": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pbkdf2": "^3.0.3" + } + }, + "node_modules/ganache-core/node_modules/secp256k1": { + "version": "4.0.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-core/node_modules/seedrandom": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/semaphore": { + "version": "1.1.0", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ganache-core/node_modules/send": { + "version": "0.17.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ganache-core/node_modules/send/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/send/node_modules/ms": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/serve-static": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ganache-core/node_modules/servify": { + "version": "0.1.12", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/set-immediate-shim": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/set-value": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/setimmediate": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/setprototypeof": { + "version": "1.1.1", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ganache-core/node_modules/sha.js": { + "version": "2.4.11", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/ganache-core/node_modules/simple-concat": { + "version": "1.0.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/simple-get": { + "version": "2.8.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon": { + "version": "0.8.2", + "dev": true, + "license": "MIT", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-node": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-util": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/source-map": { + "version": "0.5.7", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-resolve": { + "version": "0.5.3", + "dev": true, + "license": "MIT", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-support": { + "version": "0.5.12", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-url": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/split-string": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/sshpk": { + "version": "1.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/sshpk/node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "license": "Unlicense" + }, + "node_modules/ganache-core/node_modules/static-extend": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/stream-to-pull-stream": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "looper": "^3.0.0", + "pull-stream": "^3.2.3" + } + }, + "node_modules/ganache-core/node_modules/stream-to-pull-stream/node_modules/looper": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/strict-uri-encode": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/ganache-core/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/string.prototype.trim": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/string.prototype.trimend": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/string.prototype.trimstart": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/strip-hex-prefix": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js": { + "version": "0.1.40", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/fs-extra": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/get-stream": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/got": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/p-cancelable": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/prepend-http": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/url-parse-lax": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/tape": { + "version": "4.13.3", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-equal": "~1.1.1", + "defined": "~1.0.0", + "dotignore": "~0.1.2", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.6", + "has": "~1.0.3", + "inherits": "~2.0.4", + "is-regex": "~1.0.5", + "minimist": "~1.2.5", + "object-inspect": "~1.7.0", + "resolve": "~1.17.0", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.2.1", + "through": "~2.3.8" + }, + "bin": { + "tape": "bin/tape" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/glob": { + "version": "7.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/is-regex": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/object-inspect": { + "version": "1.7.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/resolve": { + "version": "1.17.0", + "dev": true, + "license": "MIT", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/tar": { + "version": "4.4.13", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/ganache-core/node_modules/tar/node_modules/fs-minipass": { + "version": "1.2.7", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/ganache-core/node_modules/tar/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/ganache-core/node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/through2": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/ganache-core/node_modules/timed-out": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/tmp": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/to-object-path": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/to-object-path/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/to-readable-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/to-regex": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/toidentifier": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/tough-cookie": { + "version": "2.5.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ganache-core/node_modules/trim-right": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/tunnel-agent": { + "version": "0.6.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/tweetnacl": { + "version": "1.0.3", + "dev": true, + "license": "Unlicense" + }, + "node_modules/ganache-core/node_modules/tweetnacl-util": { + "version": "0.15.1", + "dev": true, + "license": "Unlicense" + }, + "node_modules/ganache-core/node_modules/type": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/type-is": { + "version": "1.6.18", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/typedarray": { + "version": "0.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/typewise": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "typewise-core": "^1.2.0" + } + }, + "node_modules/ganache-core/node_modules/typewise-core": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/typewiselite": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ultron": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/underscore": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/union-value": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/ganache-core/node_modules/unorm": { + "version": "1.6.0", + "dev": true, + "license": "MIT or GPL-2.0", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ganache-core/node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/unset-value": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/ganache-core/node_modules/urix": { + "version": "0.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/url-parse-lax": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/url-set-query": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/url-to-options": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ganache-core/node_modules/use": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/utf-8-validate": { + "version": "5.0.4", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/ganache-core/node_modules/utf8": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/util.promisify": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "for-each": "^0.3.3", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ganache-core/node_modules/uuid": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/ganache-core/node_modules/varint": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/verror": { + "version": "1.10.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/ganache-core/node_modules/web3": { + "version": "1.2.11", + "dev": true, + "hasInstallScript": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "web3-bzz": "1.2.11", + "web3-core": "1.2.11", + "web3-eth": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-shh": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-bzz": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40", + "underscore": "1.9.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.19.12", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/web3-core": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-requestmanager": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-helpers": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "underscore": "1.9.1", + "web3-eth-iban": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-method": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@ethersproject/transactions": "^5.0.0-beta.135", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-promievent": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-requestmanager": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-providers-http": "1.2.11", + "web3-providers-ipc": "1.2.11", + "web3-providers-ws": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-subscriptions": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core/node_modules/@types/node": { + "version": "12.19.12", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/web3-eth": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-accounts": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-eth-ens": "1.2.11", + "web3-eth-iban": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-abi": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@ethersproject/abi": "5.0.0-beta.153", + "underscore": "1.9.1", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-accounts": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-common": "^1.3.2", + "ethereumjs-tx": "^2.1.1", + "scrypt-js": "^3.0.1", + "underscore": "1.9.1", + "uuid": "3.3.2", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-contract": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-ens": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-iban": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-personal": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.19.12", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/web3-net": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine": { + "version": "14.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^2.5.0", + "backoff": "^2.5.0", + "clone": "^2.0.0", + "cross-fetch": "^2.1.0", + "eth-block-tracker": "^3.0.0", + "eth-json-rpc-infura": "^3.1.0", + "eth-sig-util": "^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" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/eth-sig-util": { + "version": "1.4.2", + "dev": true, + "license": "ISC", + "dependencies": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "ethereumjs-util": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ws": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-providers-http": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "web3-core-helpers": "1.2.11", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-providers-ipc": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "oboe": "2.1.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-providers-ws": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "websocket": "^1.0.31" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-shh": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-net": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-utils": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.9.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-utils/node_modules/eth-lib": { + "version": "0.2.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/ganache-core/node_modules/websocket": { + "version": "1.0.32", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ganache-core/node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/whatwg-fetch": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/ws": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/ganache-core/node_modules/ws/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/xhr": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/xhr-request": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "node_modules/ganache-core/node_modules/xhr-request-promise": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "xhr-request": "^1.1.0" + } + }, + "node_modules/ganache-core/node_modules/xhr2-cookies": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "cookiejar": "^2.1.1" + } + }, + "node_modules/ganache-core/node_modules/xtend": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/yaeti": { + "version": "0.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/ganache-core/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/ghost-testrpc": { + "version": "0.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "bin": { + "testrpc-sc": "index.js" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/globals": { + "version": "13.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "9.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.6", + "dev": true, + "license": "ISC" + }, + "node_modules/growl": { + "version": "1.10.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.x" + } + }, + "node_modules/handlebars": { + "version": "4.7.7", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hardhat": { + "version": "2.7.0", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "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": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/cli.js" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/hardhat-contract-sizer": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-table3": "^0.6.0", + "colors": "^1.4.0" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.23", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat-log-remover": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-spdx-license-identifier": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat/node_modules/@types/bn.js": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/hardhat/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/hardhat/node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/has": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbol-support-x": { + "version": "1.4.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "dev": true, + "license": "ISC" + }, + "node_modules/http-basic": { + "version": "8.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-https": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "dev": true, + "license": "MIT" + }, + "node_modules/http-signature": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/husky": { + "version": "7.0.4", + "dev": true, + "license": "MIT", + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idna-uts46-hx": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.1.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/immutable": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/io-ts": { + "version": "1.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-bigint": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-date-object": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-function": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-object": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array/node_modules/es-abstract": { + "version": "1.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-string": "^1.0.7", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array/node_modules/is-callable": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array/node_modules/is-regex": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "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-typed-array/node_modules/is-string": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array/node_modules/object-inspect": { + "version": "1.11.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array/node_modules/object.assign": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/is-url": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-weakref": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isomorphic-unfetch": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/isurl": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/js-cookie": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.2.3", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonschema": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/keccak": { + "version": "3.0.1", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keyv": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/level-codec": { + "version": "9.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-concat-iterator": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/level-errors": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-iterator-stream": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-mem": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "level-packager": "^5.0.3", + "memdown": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-packager": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-supports": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-ws": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.0", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/levelup": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-cache/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/make-error": { + "version": "1.3.6", + "dev": true, + "license": "ISC" + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mcl-wasm": { + "version": "0.7.9", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memdown": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~6.2.1", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/memdown/node_modules/abstract-leveldown": { + "version": "6.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/memdown/node_modules/immediate": { + "version": "3.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/memorystream": { + "version": "0.3.1", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/merkle-patricia-tree": { + "version": "4.2.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/levelup": "^4.3.0", + "ethereumjs-util": "^7.1.2", + "level-mem": "^5.0.1", + "level-ws": "^2.0.0", + "readable-stream": "^3.6.0", + "rlp": "^2.2.4", + "semaphore-async-await": "^1.5.1" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.47.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.30", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.47.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "dev": true, + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "dev": true, + "license": "MIT" + }, + "node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "license": "ISC", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-promise": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "mkdirp": "*" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "dev": true, + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/ansi-colors": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.1" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "3.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/readdirp": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mocha/node_modules/strip-json-comments": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mock-fs": { + "version": "4.14.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/multibase": { + "version": "0.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/multicodec": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "dependencies": { + "varint": "^5.0.0" + } + }, + "node_modules/multihashes": { + "version": "0.4.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/nan": { + "version": "2.15.0", + "dev": true, + "license": "MIT" + }, + "node_modules/nano-json-stream-parser": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/next-tick": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-environment-flags": { + "version": "1.0.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node_modules/node-environment-flags/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nofilter": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "MIT" + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.9.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/oboe": { + "version": "2.1.5", + "dev": true, + "license": "BSD", + "dependencies": { + "http-https": "^1.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "7.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-locale": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-timeout": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "dev": true + }, + "node_modules/parse-headers": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/patch-package": { + "version": "6.4.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postinstall-postinstall": { + "version": "2.1.0", + "dev": true, + "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "2.5.0", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/prettier-plugin-solidity": { + "version": "1.0.0-beta.19", + "dev": true, + "license": "MIT", + "dependencies": { + "@solidity-parser/parser": "^0.14.0", + "emoji-regex": "^10.0.0", + "escape-string-regexp": "^4.0.0", + "semver": "^7.3.5", + "solidity-comments-extractor": "^0.0.7", + "string-width": "^4.2.3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "prettier": "^2.3.0" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/emoji-regex": { + "version": "10.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/prettier-plugin-solidity/node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/printj": { + "version": "1.1.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "printj": "bin/printj.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/process": { + "version": "0.11.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/psl": { + "version": "1.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.10.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.1", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/http-errors": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body/node_modules/setprototypeof": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/raw-body/node_modules/toidentifier": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/read-pkg": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "3.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/req-cwd": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from/node_modules/resolve-from": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/request": { + "version": "2.88.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "dev": true, + "license": "ISC", + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "dev": true, + "license": "ISC", + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/resolve": { + "version": "1.17.0", + "dev": true, + "license": "MIT", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.6", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.1" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rustbn.js": { + "version": "0.2.0", + "dev": true, + "license": "(MIT OR Apache-2.0)" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/sc-istanbul": { + "version": "0.4.6", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/sc-istanbul/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/sc-istanbul/node_modules/esprima": { + "version": "2.7.3", + "dev": true, + "license": "BSD-2-Clause", + "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", + "dev": true, + "license": "ISC", + "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", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/resolve": { + "version": "1.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/sc-istanbul/node_modules/supports-color": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "4.0.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semaphore-async-await": { + "version": "1.5.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.1" + } + }, + "node_modules/semver": { + "version": "7.3.5", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.17.1", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/servify": { + "version": "0.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sha1": { + "version": "1.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shelljs": { + "version": "0.8.4", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "2.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/solc": { + "version": "0.7.3", + "dev": true, + "license": "MIT", + "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/solc/node_modules/follow-redirects": { + "version": "1.14.5", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solidity-comments-extractor": { + "version": "0.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/solidity-coverage": { + "version": "0.7.17", + "dev": true, + "license": "ISC", + "dependencies": { + "@solidity-parser/parser": "^0.13.2", + "@truffle/provider": "^0.2.24", + "chalk": "^2.4.2", + "death": "^1.1.0", + "detect-port": "^1.3.0", + "fs-extra": "^8.1.0", + "ganache-cli": "^6.12.2", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.15", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.0" + }, + "bin": { + "solidity-coverage": "plugins/bin.js" + } + }, + "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { + "version": "0.13.2", + "dev": true, + "license": "MIT", + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/solidity-coverage/node_modules/fs-extra": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/solidity-coverage/node_modules/globby": { + "version": "10.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/solidity-coverage/node_modules/pify": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.9", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/sshpk": { + "version": "1.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sshpk/node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "license": "Unlicense" + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js": { + "version": "0.1.40", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + } + }, + "node_modules/swarm-js/node_modules/eth-lib": { + "version": "0.1.29", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/swarm-js/node_modules/fs-extra": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/swarm-js/node_modules/get-stream": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js/node_modules/got": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js/node_modules/p-cancelable": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js/node_modules/prepend-http": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swarm-js/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/swarm-js/node_modules/url-parse-lax": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swarm-js/node_modules/ws": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/test-value": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^1.0.3", + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/test-value/node_modules/array-back": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/testrpc": { + "version": "0.0.1", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/then-request": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "dev": true, + "license": "MIT" + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/timed-out": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/true-case-path": { + "version": "2.2.1", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/ts-essentials": { + "version": "1.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/ts-generator": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mkdirp": "^0.5.2", + "@types/prettier": "^2.1.1", + "@types/resolve": "^0.0.8", + "chalk": "^2.4.1", + "glob": "^7.1.2", + "mkdirp": "^0.5.1", + "prettier": "^2.1.2", + "resolve": "^1.8.1", + "ts-essentials": "^1.0.0" + }, + "bin": { + "ts-generator": "dist/cli/run.js" + } + }, + "node_modules/ts-node": { + "version": "10.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.7.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", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.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", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/tsort": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "dev": true, + "license": "Unlicense" + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "dev": true, + "license": "Unlicense" + }, + "node_modules/type": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typechain": { + "version": "6.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prettier": "^2.1.1", + "command-line-args": "^4.0.7", + "debug": "^4.1.1", + "fs-extra": "^7.0.0", + "glob": "^7.1.6", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.1.2", + "ts-essentials": "^7.0.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.1.0" + } + }, + "node_modules/typechain/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typechain/node_modules/ts-essentials": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.5.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typical": { + "version": "2.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/uglify-js": { + "version": "3.14.2", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ultron": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.9.1", + "dev": true, + "license": "MIT" + }, + "node_modules/unfetch": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url-set-query": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/url-to-options": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utf-8-validate": { + "version": "5.0.6", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.4", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/varint": { + "version": "5.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/web3": { + "version": "1.5.3", + "dev": true, + "hasInstallScript": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-bzz": "1.5.3", + "web3-core": "1.5.3", + "web3-eth": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-shh": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-bzz": { + "version": "1.5.3", + "dev": true, + "hasInstallScript": true, + "license": "LGPL-3.0", + "dependencies": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.20.27", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-requestmanager": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-helpers": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-helpers/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethereumjs/common": "^2.4.0", + "@ethersproject/transactions": "^5.0.0-beta.135", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-promievent": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-requestmanager": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "util": "^0.12.0", + "web3-core-helpers": "1.5.3", + "web3-providers-http": "1.5.3", + "web3-providers-ipc": "1.5.3", + "web3-providers-ws": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-subscriptions": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/@types/node": { + "version": "12.20.27", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-accounts": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-eth-ens": "1.5.3", + "web3-eth-iban": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { + "version": "5.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/web3-eth-abi/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethereumjs/common": "^2.3.0", + "@ethereumjs/tx": "^3.2.1", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/@types/bn.js": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/web3-eth-accounts/node_modules/bn.js": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-accounts/node_modules/ethereumjs-util": { + "version": "7.1.1", + "dev": true, + "license": "MPL-2.0", + "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" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-utils/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-contract": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@types/bn.js": "^4.11.5", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.20.27", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-personal/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-net": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-net/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-http": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-core-helpers": "1.5.3", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ipc": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "oboe": "2.1.5", + "web3-core-helpers": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ws": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3", + "websocket": "^1.0.32" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-shh": { + "version": "1.5.3", + "dev": true, + "hasInstallScript": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-net": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils": { + "version": "1.3.5", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.9.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3/node_modules/web3-utils": { + "version": "1.5.3", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/websocket": { + "version": "1.0.34", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "1.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/which-typed-array": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array/node_modules/es-abstract": { + "version": "1.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-string": "^1.0.7", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array/node_modules/is-callable": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array/node_modules/is-regex": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array/node_modules/is-string": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array/node_modules/object-inspect": { + "version": "1.11.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array/node_modules/object.assign": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/window-size": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.4.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xhr": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/xhr-request": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "node_modules/xhr-request-promise": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xhr-request": "^1.1.0" + } + }, + "node_modules/xhr2-cookies": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cookiejar": "^2.1.1" + } + }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/yaeti": { + "version": "0.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "13.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs-unparser": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/locate-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/p-locate": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@ensdomains/ens": { + "version": "0.4.5", + "dev": true, + "requires": { + "bluebird": "^3.5.2", + "eth-ens-namehash": "^2.0.8", + "solc": "^0.4.20", + "testrpc": "0.0.1", + "web3-utils": "^1.0.0-beta.31" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "fs-extra": { + "version": "0.30.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "get-caller-file": { + "version": "1.0.3", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "jsonfile": { + "version": "2.4.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "require-from-string": { + "version": "1.2.1", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "dev": true + }, + "semver": { + "version": "5.7.1", + "dev": true + }, + "solc": { + "version": "0.4.26", + "dev": true, + "requires": { + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" + } + }, + "string-width": { + "version": "1.0.2", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "y18n": { + "version": "3.2.2", + "dev": true + }, + "yargs": { + "version": "4.8.1", + "dev": true, + "requires": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "yargs-parser": { + "version": "2.4.1", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + } + } + }, + "@ensdomains/resolver": { + "version": "0.2.4", + "dev": true + }, + "@eslint/eslintrc": { + "version": "1.0.4", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.0.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "dev": true + }, + "debug": { + "version": "4.3.3", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ignore": { + "version": "4.0.6", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, + "@ethereum-waffle/chai": { + "version": "3.4.0", + "dev": true, + "requires": { + "@ethereum-waffle/provider": "^3.4.0", + "ethers": "^5.0.0" + } + }, + "@ethereum-waffle/compiler": { + "version": "3.4.0", + "dev": true, + "requires": { + "@resolver-engine/imports": "^0.3.3", + "@resolver-engine/imports-fs": "^0.3.3", + "@typechain/ethers-v5": "^2.0.0", + "@types/mkdirp": "^0.5.2", + "@types/node-fetch": "^2.5.5", + "ethers": "^5.0.1", + "mkdirp": "^0.5.1", + "node-fetch": "^2.6.1", + "solc": "^0.6.3", + "ts-generator": "^0.1.1", + "typechain": "^3.0.0" + }, + "dependencies": { + "@typechain/ethers-v5": { + "version": "2.0.0", + "dev": true, + "requires": { + "ethers": "^5.0.2" + } + }, + "jsonfile": { + "version": "2.4.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "semver": { + "version": "5.7.1", + "dev": true + }, + "solc": { + "version": "0.6.12", + "dev": true, + "requires": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + } + } + }, + "ts-essentials": { + "version": "6.0.7", + "dev": true, + "requires": {} + }, + "typechain": { + "version": "3.0.0", + "dev": true, + "requires": { + "command-line-args": "^4.0.7", + "debug": "^4.1.1", + "fs-extra": "^7.0.0", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "ts-essentials": "^6.0.3", + "ts-generator": "^0.1.1" + } + } + } + }, + "@ethereum-waffle/ens": { + "version": "3.3.0", + "dev": true, + "requires": { + "@ensdomains/ens": "^0.4.4", + "@ensdomains/resolver": "^0.2.4", + "ethers": "^5.0.1" + } + }, + "@ethereum-waffle/mock-contract": { + "version": "3.3.0", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.0.1", + "ethers": "^5.0.1" + } + }, + "@ethereum-waffle/provider": { + "version": "3.4.0", + "dev": true, + "requires": { + "@ethereum-waffle/ens": "^3.3.0", + "ethers": "^5.0.1", + "ganache-core": "^2.13.2", + "patch-package": "^6.2.2", + "postinstall-postinstall": "^2.1.0" + } + }, + "@ethereumjs/block": { + "version": "3.6.0", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/tx": "^3.4.0", + "ethereumjs-util": "^7.1.3", + "merkle-patricia-tree": "^4.2.2" + }, + "dependencies": { + "@ethereumjs/common": { + "version": "2.6.0", + "dev": true, + "requires": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.3" + } + }, + "@ethereumjs/tx": { + "version": "3.4.0", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.6.0", + "ethereumjs-util": "^7.1.3" + } + } + } + }, + "@ethereumjs/blockchain": { + "version": "5.5.1", + "dev": true, + "requires": { + "@ethereumjs/block": "^3.6.0", + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/ethash": "^1.1.0", + "debug": "^2.2.0", + "ethereumjs-util": "^7.1.3", + "level-mem": "^5.0.1", + "lru-cache": "^5.1.1", + "semaphore-async-await": "^1.5.1" + }, + "dependencies": { + "@ethereumjs/common": { + "version": "2.6.0", + "dev": true, + "requires": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.3" + } + }, + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "@ethereumjs/common": { + "version": "2.4.0", + "dev": true, + "requires": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.0" + }, + "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "5.2.0", + "dev": true + }, + "ethereumjs-util": { + "version": "7.1.0", + "dev": true, + "requires": { + "@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/ethash": { + "version": "1.1.0", + "dev": true, + "requires": { + "@ethereumjs/block": "^3.5.0", + "@types/levelup": "^4.3.0", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.1.1", + "miller-rabin": "^4.0.0" + }, + "dependencies": { + "buffer-xor": { + "version": "2.0.2", + "dev": true, + "requires": { + "safe-buffer": "^5.1.1" + } + } + } + }, + "@ethereumjs/tx": { + "version": "3.3.0", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.4.0", + "ethereumjs-util": "^7.1.0" + }, + "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "5.2.0", + "dev": true + }, + "ethereumjs-util": { + "version": "7.1.0", + "dev": true, + "requires": { + "@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/vm": { + "version": "5.6.0", + "dev": true, + "requires": { + "@ethereumjs/block": "^3.6.0", + "@ethereumjs/blockchain": "^5.5.0", + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/tx": "^3.4.0", + "async-eventemitter": "^0.2.4", + "core-js-pure": "^3.0.1", + "debug": "^2.2.0", + "ethereumjs-util": "^7.1.3", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "merkle-patricia-tree": "^4.2.2", + "rustbn.js": "~0.2.0" + }, + "dependencies": { + "@ethereumjs/common": { + "version": "2.6.0", + "dev": true, + "requires": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.3" + } + }, + "@ethereumjs/tx": { + "version": "3.4.0", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.6.0", + "ethereumjs-util": "^7.1.3" + } + }, + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "@ethersproject/abi": { + "version": "5.3.1", + "dev": true, + "requires": { + "@ethersproject/address": "^5.3.0", + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/constants": "^5.3.0", + "@ethersproject/hash": "^5.3.0", + "@ethersproject/keccak256": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/strings": "^5.3.0" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/networks": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/transactions": "^5.3.0", + "@ethersproject/web": "^5.3.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.3.0", + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0" + } + }, + "@ethersproject/address": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/keccak256": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/rlp": "^5.3.0" + } + }, + "@ethersproject/base64": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.3.0" + } + }, + "@ethersproject/basex": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + }, + "@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + } + } + }, + "@ethersproject/bignumber": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.3.0" + } + }, + "@ethersproject/constants": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.3.0" + } + }, + "@ethersproject/contracts": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.5.0", + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0" + }, + "dependencies": { + "@ethersproject/abi": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + } + } + }, + "@ethersproject/hash": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.3.0", + "@ethersproject/address": "^5.3.0", + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/keccak256": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/strings": "^5.3.0" + } + }, + "@ethersproject/hdnode": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/basex": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/pbkdf2": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/wordlists": "^5.5.0" + }, + "dependencies": { + "@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + } + } + }, + "@ethersproject/json-wallets": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hdnode": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/pbkdf2": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + }, + "dependencies": { + "@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + } + } + }, + "@ethersproject/keccak256": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.3.0", + "js-sha3": "0.5.7" + }, + "dependencies": { + "js-sha3": { + "version": "0.5.7", + "dev": true + } + } + }, + "@ethersproject/logger": { + "version": "5.3.0", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.3.1", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.3.0" + } + }, + "@ethersproject/pbkdf2": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/sha2": "^5.5.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + } + } + }, + "@ethersproject/properties": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.3.0" + } + }, + "@ethersproject/providers": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/basex": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0", + "bech32": "1.1.4", + "ws": "7.4.6" + }, + "dependencies": { + "@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + } + } + }, + "@ethersproject/random": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + } + } + }, + "@ethersproject/rlp": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0" + } + }, + "@ethersproject/sha2": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "hash.js": "1.1.7" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + } + } + }, + "@ethersproject/signing-key": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/solidity": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + }, + "@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + } + } + }, + "@ethersproject/strings": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/constants": "^5.3.0", + "@ethersproject/logger": "^5.3.0" + } + }, + "@ethersproject/transactions": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.3.0", + "@ethersproject/bignumber": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/constants": "^5.3.0", + "@ethersproject/keccak256": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/rlp": "^5.3.0", + "@ethersproject/signing-key": "^5.3.0" + } + }, + "@ethersproject/units": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + } + } + }, + "@ethersproject/wallet": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/hdnode": "^5.5.0", + "@ethersproject/json-wallets": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/wordlists": "^5.5.0" + }, + "dependencies": { + "@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + } + } + }, + "@ethersproject/web": { + "version": "5.3.0", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.3.0", + "@ethersproject/bytes": "^5.3.0", + "@ethersproject/logger": "^5.3.0", + "@ethersproject/properties": "^5.3.0", + "@ethersproject/strings": "^5.3.0" + } + }, + "@ethersproject/wordlists": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + }, + "dependencies": { + "@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.6.0", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.4", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.4", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.6", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + } + }, + "@nomiclabs/hardhat-ethers": { + "version": "2.0.2", + "dev": true, + "requires": {} + }, + "@nomiclabs/hardhat-etherscan": { + "version": "2.1.8", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^5.0.2", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "node-fetch": "^2.6.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "dev": true + } + } + }, + "@openzeppelin/contracts": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.5.0.tgz", + "integrity": "sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA==" + }, + "@resolver-engine/core": { + "version": "0.3.3", + "dev": true, + "requires": { + "debug": "^3.1.0", + "is-url": "^1.2.4", + "request": "^2.85.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@resolver-engine/fs": { + "version": "0.3.3", + "dev": true, + "requires": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@resolver-engine/imports": { + "version": "0.3.3", + "dev": true, + "requires": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0", + "hosted-git-info": "^2.6.0", + "path-browserify": "^1.0.0", + "url": "^0.11.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@resolver-engine/imports-fs": { + "version": "0.3.3", + "dev": true, + "requires": { + "@resolver-engine/fs": "^0.3.3", + "@resolver-engine/imports": "^0.3.3", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@sentry/core": { + "version": "5.30.0", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/hub": { + "version": "5.30.0", + "dev": true, + "requires": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/minimal": { + "version": "5.30.0", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/node": { + "version": "5.30.0", + "dev": true, + "requires": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + } + }, + "@sentry/tracing": { + "version": "5.30.0", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/types": { + "version": "5.30.0", + "dev": true + }, + "@sentry/utils": { + "version": "5.30.0", + "dev": true, + "requires": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "dev": true + }, + "@solidity-parser/parser": { + "version": "0.14.0", + "dev": true, + "requires": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@truffle/error": { + "version": "0.0.14", + "dev": true + }, + "@truffle/interface-adapter": { + "version": "0.5.7", + "dev": true, + "requires": { + "bn.js": "^5.1.3", + "ethers": "^4.0.32", + "web3": "1.5.3" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "dev": true + }, + "ethers": { + "version": "4.0.49", + "dev": true, + "requires": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "dev": true + } + } + }, + "hash.js": { + "version": "1.1.3", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "js-sha3": { + "version": "0.5.7", + "dev": true + }, + "scrypt-js": { + "version": "2.0.4", + "dev": true + }, + "setimmediate": { + "version": "1.0.4", + "dev": true + }, + "uuid": { + "version": "2.0.1", + "dev": true + } + } + }, + "@truffle/provider": { + "version": "0.2.41", + "dev": true, + "requires": { + "@truffle/error": "^0.0.14", + "@truffle/interface-adapter": "^0.5.7", + "web3": "1.5.3" + } + }, + "@tsconfig/node10": { + "version": "1.0.8", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "dev": true + }, + "@typechain/ethers-v5": { + "version": "8.0.5", + "dev": true, + "requires": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + }, + "dependencies": { + "ts-essentials": { + "version": "7.0.3", + "dev": true, + "requires": {} + } + } + }, + "@typechain/hardhat": { + "version": "3.0.0", + "dev": true, + "requires": { + "fs-extra": "^9.1.0" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "dev": true + } + } + }, + "@types/abstract-leveldown": { + "version": "5.0.2", + "dev": true + }, + "@types/bn.js": { + "version": "4.11.6", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/chai": { + "version": "4.2.22", + "dev": true + }, + "@types/concat-stream": { + "version": "1.6.1", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/glob": { + "version": "7.1.4", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.9", + "dev": true + }, + "@types/level-errors": { + "version": "3.0.0", + "dev": true + }, + "@types/levelup": { + "version": "4.3.3", + "dev": true, + "requires": { + "@types/abstract-leveldown": "*", + "@types/level-errors": "*", + "@types/node": "*" + } + }, + "@types/lru-cache": { + "version": "5.1.1", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.5", + "dev": true + }, + "@types/mkdirp": { + "version": "0.5.2", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "9.0.0", + "dev": true + }, + "@types/node": { + "version": "16.11.11", + "dev": true + }, + "@types/node-fetch": { + "version": "2.5.10", + "dev": true, + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "@types/pbkdf2": { + "version": "3.1.0", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/prettier": { + "version": "2.2.3", + "dev": true + }, + "@types/qs": { + "version": "6.9.7", + "dev": true + }, + "@types/resolve": { + "version": "0.0.8", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.2", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.5.0", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "5.5.0", + "@typescript-eslint/scope-manager": "5.5.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "5.5.0", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.5.0", + "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/typescript-estree": "5.5.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.5.0", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.5.0", + "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/typescript-estree": "5.5.0", + "debug": "^4.3.2" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.5.0", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/visitor-keys": "5.5.0" + } + }, + "@typescript-eslint/types": { + "version": "5.5.0", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.5.0", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/visitor-keys": "5.5.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "is-glob": { + "version": "4.0.3", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.5.0", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.5.0", + "eslint-visitor-keys": "^3.0.0" + } + }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true + }, + "abbrev": { + "version": "1.0.9", + "dev": true + }, + "abort-controller": { + "version": "3.0.0", + "dev": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "abstract-leveldown": { + "version": "6.3.0", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "accepts": { + "version": "1.3.7", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "8.6.0", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "dev": true, + "requires": {} + }, + "acorn-walk": { + "version": "8.2.0", + "dev": true + }, + "address": { + "version": "1.1.2", + "dev": true + }, + "adm-zip": { + "version": "0.4.16", + "dev": true + }, + "aes-js": { + "version": "3.0.0", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "dev": true, + "requires": { + "debug": "4" + } + }, + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "amazon-cognito-identity-js": { + "version": "4.6.3", + "dev": true, + "requires": { + "buffer": "4.9.2", + "crypto-js": "^4.0.0", + "fast-base64-decode": "^1.0.0", + "isomorphic-unfetch": "^3.0.0", + "js-cookie": "^2.2.1" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + } + } + }, + "amdefine": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "ansi-colors": { + "version": "4.1.1", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "antlr4ts": { + "version": "0.5.0-alpha.4", + "dev": true + }, + "anymatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-back": { + "version": "2.0.0", + "dev": true, + "requires": { + "typical": "^2.6.1" + } + }, + "array-flatten": { + "version": "1.1.1", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "dev": true + }, + "array-uniq": { + "version": "1.0.3", + "dev": true + }, + "asap": { + "version": "2.0.6", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "dev": true + }, + "async": { + "version": "2.6.3", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-eventemitter": { + "version": "0.2.4", + "dev": true, + "requires": { + "async": "^2.4.0" + } + }, + "async-limiter": { + "version": "1.0.1", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "dev": true + }, + "available-typed-arrays": { + "version": "1.0.5", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "dev": true + }, + "axios": { + "version": "0.19.2", + "dev": true, + "requires": { + "follow-redirects": "1.5.10" + } + }, + "balanced-match": { + "version": "1.0.2", + "dev": true + }, + "base-x": { + "version": "3.0.8", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "dev": true + } + } + }, + "bech32": { + "version": "1.1.4", + "dev": true + }, + "bignumber.js": { + "version": "9.0.1", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "dev": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip66": { + "version": "1.1.5", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "blakejs": { + "version": "1.1.0", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "dev": true + }, + "bn.js": { + "version": "4.12.0", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "inherits": { + "version": "2.0.3", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + }, + "qs": { + "version": "6.7.0", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "dev": true + }, + "browser-stdout": { + "version": "1.3.1", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "dev": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "dev": true + } + } + }, + "browserify-sign": { + "version": "4.2.1", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "dev": true + } + } + }, + "bs58": { + "version": "4.0.1", + "dev": true, + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "dev": true, + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "5.7.1", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.2", + "dev": true + }, + "buffer-to-arraybuffer": { + "version": "0.0.5", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "dev": true + }, + "bufferutil": { + "version": "4.0.4", + "dev": true, + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "bytes": { + "version": "3.1.0", + "dev": true + }, + "cacheable-request": { + "version": "6.1.0", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "dev": true + }, + "cbor": { + "version": "5.2.0", + "dev": true, + "requires": { + "bignumber.js": "^9.0.1", + "nofilter": "^1.0.4" + } + }, + "chai": { + "version": "4.3.4", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "charenc": { + "version": "0.0.2", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "dev": true + }, + "chokidar": { + "version": "3.5.2", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chownr": { + "version": "1.1.4", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "dev": true + }, + "cids": { + "version": "0.7.5", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "dependencies": { + "multicodec": { + "version": "1.0.4", + "dev": true, + "requires": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + } + } + }, + "cipher-base": { + "version": "1.0.4", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-is": { + "version": "1.1.0", + "dev": true + }, + "cli-table3": { + "version": "0.6.0", + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "clone-response": { + "version": "1.0.2", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "dev": true + }, + "colors": { + "version": "1.4.0", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "command-exists": { + "version": "1.2.9", + "dev": true + }, + "command-line-args": { + "version": "4.0.7", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "find-replace": "^1.0.3", + "typical": "^2.6.1" + } + }, + "commander": { + "version": "3.0.2", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "content-disposition": { + "version": "0.5.3", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "content-hash": { + "version": "2.5.2", + "dev": true, + "requires": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "content-type": { + "version": "1.0.4", + "dev": true + }, + "cookie": { + "version": "0.4.1", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "dev": true + }, + "cookiejar": { + "version": "2.1.2", + "dev": true + }, + "core-js-pure": { + "version": "3.19.2", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "dev": true + }, + "cors": { + "version": "2.8.5", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "crc-32": { + "version": "1.2.0", + "dev": true, + "requires": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.1.0" + } + }, + "create-ecdh": { + "version": "4.0.4", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "create-hash": { + "version": "1.2.0", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-require": { + "version": "1.1.1", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "dev": true + } + } + }, + "crypt": { + "version": "0.0.2", + "dev": true + }, + "crypto-browserify": { + "version": "3.12.0", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-js": { + "version": "4.1.1", + "dev": true + }, + "d": { + "version": "1.0.1", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "death": { + "version": "1.1.0", + "dev": true + }, + "debug": { + "version": "4.3.1", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "dev": true + }, + "decompress-response": { + "version": "3.3.0", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "dev": true + }, + "defender-base-client": { + "version": "1.12.1", + "dev": true, + "requires": { + "amazon-cognito-identity-js": "^4.3.3", + "axios": "^0.19.2", + "lodash": "^4.17.19", + "node-fetch": "^2.6.0" + } + }, + "defender-relay-client": { + "version": "1.12.1", + "dev": true, + "requires": { + "amazon-cognito-identity-js": "^4.3.3", + "axios": "^0.19.2", + "defender-base-client": "^1.12.1", + "lodash": "^4.17.19", + "node-fetch": "^2.6.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "dev": true + }, + "deferred-leveldown": { + "version": "5.3.0", + "dev": true, + "requires": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "dependencies": { + "abstract-leveldown": { + "version": "6.2.3", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + } + } + }, + "define-properties": { + "version": "1.1.3", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "dev": true + }, + "depd": { + "version": "1.1.2", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "dev": true + }, + "detect-port": { + "version": "1.3.0", + "dev": true, + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "diff": { + "version": "3.5.0", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "3.0.1", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "dev": true + } + } + }, + "doctrine": { + "version": "3.0.0", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-walk": { + "version": "0.1.2", + "dev": true + }, + "dotenv": { + "version": "10.0.0", + "dev": true + }, + "drbg.js": { + "version": "1.0.1", + "dev": true, + "requires": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + } + }, + "duplexer3": { + "version": "0.1.4", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "emoji-regex": { + "version": "7.0.3", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "dev": true + }, + "encoding-down": { + "version": "6.3.0", + "dev": true, + "requires": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + } + }, + "end-of-stream": { + "version": "1.4.4", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "env-paths": { + "version": "2.2.1", + "dev": true + }, + "errno": { + "version": "0.1.8", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.19.1", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "dependencies": { + "is-callable": { + "version": "1.2.4", + "dev": true + }, + "is-string": { + "version": "1.0.7", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, + "es-to-primitive": { + "version": "1.2.1", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "escape-html": { + "version": "1.0.3", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "dev": true + }, + "levn": { + "version": "0.3.0", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "type-check": { + "version": "0.3.2", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "eslint": { + "version": "8.3.0", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.0.4", + "@humanwhocodes/config-array": "^0.6.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.1.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.3", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "dev": true + }, + "eslint-scope": { + "version": "7.1.0", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + }, + "dependencies": { + "is-glob": { + "version": "4.0.3", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + } + } + }, + "has-flag": { + "version": "4.0.0", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "which": { + "version": "2.0.2", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "eslint-config-prettier": { + "version": "8.3.0", + "dev": true, + "requires": {} + }, + "eslint-plugin-prettier": { + "version": "4.0.0", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "3.0.0", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.1.0", + "dev": true + }, + "espree": { + "version": "9.1.0", + "dev": true, + "requires": { + "acorn": "^8.6.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "dev": true + }, + "etag": { + "version": "1.8.1", + "dev": true + }, + "eth-ens-namehash": { + "version": "2.0.8", + "dev": true, + "requires": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + }, + "dependencies": { + "js-sha3": { + "version": "0.5.7", + "dev": true + } + } + }, + "eth-gas-reporter": { + "version": "0.2.23", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.0.0-beta.146", + "@solidity-parser/parser": "^0.14.0", + "cli-table3": "^0.5.0", + "colors": "^1.1.2", + "ethereumjs-util": "6.2.0", + "ethers": "^4.0.40", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^7.1.1", + "req-cwd": "^2.0.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "dependencies": { + "cli-table3": { + "version": "0.5.1", + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, + "ethereumjs-util": { + "version": "6.2.0", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "0.1.6", + "keccak": "^2.0.0", + "rlp": "^2.2.3", + "secp256k1": "^3.0.1" + } + }, + "ethers": { + "version": "4.0.49", + "dev": true, + "requires": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "hash.js": { + "version": "1.1.3", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "js-sha3": { + "version": "0.5.7", + "dev": true + }, + "keccak": { + "version": "2.1.0", + "dev": true, + "requires": { + "bindings": "^1.5.0", + "inherits": "^2.0.4", + "nan": "^2.14.0", + "safe-buffer": "^5.2.0" + } + }, + "scrypt-js": { + "version": "2.0.4", + "dev": true + }, + "secp256k1": { + "version": "3.8.0", + "dev": true, + "requires": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.5.2", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + } + }, + "setimmediate": { + "version": "1.0.4", + "dev": true + }, + "uuid": { + "version": "2.0.1", + "dev": true + } + } + }, + "eth-lib": { + "version": "0.2.8", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "eth-sig-util": { + "version": "2.5.4", + "dev": true, + "requires": { + "ethereumjs-abi": "0.6.8", + "ethereumjs-util": "^5.1.1", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.0" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "ethereum-bloom-filters": { + "version": "1.0.9", + "dev": true, + "requires": { + "js-sha3": "^0.8.0" + } + }, + "ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "ethereum-waffle": { + "version": "3.4.0", + "dev": true, + "requires": { + "@ethereum-waffle/chai": "^3.4.0", + "@ethereum-waffle/compiler": "^3.4.0", + "@ethereum-waffle/mock-contract": "^3.3.0", + "@ethereum-waffle/provider": "^3.4.0", + "ethers": "^5.0.1" + } + }, + "ethereumjs-abi": { + "version": "git+ssh://git@github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0", + "dev": true, + "from": "ethereumjs-abi@0.6.8", + "requires": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + }, + "dependencies": { + "ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, + "ethereumjs-util": { + "version": "7.1.3", + "dev": true, + "requires": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "5.2.0", + "dev": true + } + } + }, + "ethers": { + "version": "5.5.1", + "dev": true, + "requires": { + "@ethersproject/abi": "5.5.0", + "@ethersproject/abstract-provider": "5.5.1", + "@ethersproject/abstract-signer": "5.5.0", + "@ethersproject/address": "5.5.0", + "@ethersproject/base64": "5.5.0", + "@ethersproject/basex": "5.5.0", + "@ethersproject/bignumber": "5.5.0", + "@ethersproject/bytes": "5.5.0", + "@ethersproject/constants": "5.5.0", + "@ethersproject/contracts": "5.5.0", + "@ethersproject/hash": "5.5.0", + "@ethersproject/hdnode": "5.5.0", + "@ethersproject/json-wallets": "5.5.0", + "@ethersproject/keccak256": "5.5.0", + "@ethersproject/logger": "5.5.0", + "@ethersproject/networks": "5.5.0", + "@ethersproject/pbkdf2": "5.5.0", + "@ethersproject/properties": "5.5.0", + "@ethersproject/providers": "5.5.0", + "@ethersproject/random": "5.5.0", + "@ethersproject/rlp": "5.5.0", + "@ethersproject/sha2": "5.5.0", + "@ethersproject/signing-key": "5.5.0", + "@ethersproject/solidity": "5.5.0", + "@ethersproject/strings": "5.5.0", + "@ethersproject/transactions": "5.5.0", + "@ethersproject/units": "5.5.0", + "@ethersproject/wallet": "5.5.0", + "@ethersproject/web": "5.5.0", + "@ethersproject/wordlists": "5.5.0" + }, + "dependencies": { + "@ethersproject/abi": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.5.1", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" + } + }, + "@ethersproject/address": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" + } + }, + "@ethersproject/base64": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/constants": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.5.0" + } + }, + "@ethersproject/hash": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/properties": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/rlp": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/transactions": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" + } + }, + "@ethersproject/web": { + "version": "5.5.0", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" + } + } + } + }, + "ethjs-unit": { + "version": "0.1.6", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "dev": true + } + } + }, + "ethjs-util": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + } + }, + "event-target-shim": { + "version": "5.0.1", + "dev": true + }, + "eventemitter3": { + "version": "4.0.4", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "exit-on-epipe": { + "version": "1.0.1", + "dev": true + }, + "express": { + "version": "4.17.1", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "cookie": { + "version": "0.4.0", + "dev": true + }, + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + }, + "qs": { + "version": "6.7.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "ext": { + "version": "1.6.0", + "dev": true, + "requires": { + "type": "^2.5.0" + }, + "dependencies": { + "type": { + "version": "2.5.0", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "dev": true + }, + "fast-base64-decode": { + "version": "1.0.0", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "dev": true + }, + "fast-glob": { + "version": "3.2.5", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "dev": true + }, + "fastq": { + "version": "1.11.0", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "find-replace": { + "version": "1.0.3", + "dev": true, + "requires": { + "array-back": "^1.0.4", + "test-value": "^2.1.0" + }, + "dependencies": { + "array-back": { + "version": "1.0.4", + "dev": true, + "requires": { + "typical": "^2.6.0" + } + } + } + }, + "find-up": { + "version": "2.1.0", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "find-yarn-workspace-root": { + "version": "2.0.0", + "dev": true, + "requires": { + "micromatch": "^4.0.2" + } + }, + "flat": { + "version": "4.1.1", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, + "flat-cache": { + "version": "3.0.4", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.2.4", + "dev": true + }, + "follow-redirects": { + "version": "1.5.10", + "dev": true, + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "foreach": { + "version": "2.0.5", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "dev": true + }, + "form-data": { + "version": "3.0.1", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "dev": true + }, + "fp-ts": { + "version": "1.19.3", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "dev": true + }, + "fs-extra": { + "version": "7.0.1", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.7", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "dev": true + }, + "ganache-cli": { + "version": "6.12.2", + "dev": true, + "requires": { + "ethereumjs-util": "6.2.1", + "source-map-support": "0.5.12", + "yargs": "13.2.4" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "bundled": true, + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "14.11.2", + "bundled": true, + "dev": true + }, + "@types/pbkdf2": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "ansi-regex": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "bundled": true, + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "base-x": { + "version": "3.0.8", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "blakejs": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "bn.js": { + "version": "4.11.9", + "bundled": true, + "dev": true + }, + "brorand": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "bs58": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer-from": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "bundled": true, + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "cliui": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "color-convert": { + "version": "1.9.3", + "bundled": true, + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "create-hash": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "bundled": true, + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "bundled": true, + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "ethereum-cryptography": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "bundled": true, + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "ethjs-util": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "hash-base": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-hex-prefixed": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "keccak": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mem": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "node-addon-api": { + "version": "2.0.2", + "bundled": true, + "dev": true + }, + "node-gyp-build": { + "version": "4.2.3", + "bundled": true, + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "pbkdf2": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "randombytes": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "ripemd160": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rlp": { + "version": "2.2.6", + "bundled": true, + "dev": true, + "requires": { + "bn.js": "^4.11.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "bundled": true, + "dev": true + }, + "scrypt-js": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "secp256k1": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + }, + "source-map-support": { + "version": "0.5.12", + "bundled": true, + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "strip-hex-prefix": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "13.2.4", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.2", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "ganache-core": { + "version": "2.13.2", + "dev": true, + "requires": { + "abstract-leveldown": "3.0.0", + "async": "2.6.2", + "bip39": "2.5.0", + "cachedown": "1.0.0", + "clone": "2.1.2", + "debug": "3.2.6", + "encoding-down": "5.0.4", + "eth-sig-util": "3.0.0", + "ethereumjs-abi": "0.6.8", + "ethereumjs-account": "3.0.0", + "ethereumjs-block": "2.2.2", + "ethereumjs-common": "1.5.0", + "ethereumjs-tx": "2.1.2", + "ethereumjs-util": "6.2.1", + "ethereumjs-vm": "4.2.0", + "ethereumjs-wallet": "0.6.5", + "heap": "0.2.6", + "keccak": "3.0.1", + "level-sublevel": "6.6.4", + "levelup": "3.1.1", + "lodash": "4.17.20", + "lru-cache": "5.1.1", + "merkle-patricia-tree": "3.0.0", + "patch-package": "6.2.2", + "seedrandom": "3.0.1", + "source-map-support": "0.5.12", + "tmp": "0.1.0", + "web3": "1.2.11", + "web3-provider-engine": "14.2.1", + "websocket": "1.0.32" + }, + "dependencies": { + "@ethersproject/abi": { + "version": "5.0.0-beta.153", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/address": ">=5.0.0-beta.128", + "@ethersproject/bignumber": ">=5.0.0-beta.130", + "@ethersproject/bytes": ">=5.0.0-beta.129", + "@ethersproject/constants": ">=5.0.0-beta.128", + "@ethersproject/hash": ">=5.0.0-beta.128", + "@ethersproject/keccak256": ">=5.0.0-beta.127", + "@ethersproject/logger": ">=5.0.0-beta.129", + "@ethersproject/properties": ">=5.0.0-beta.131", + "@ethersproject/strings": ">=5.0.0-beta.130" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.0.8", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/networks": "^5.0.7", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/transactions": "^5.0.9", + "@ethersproject/web": "^5.0.12" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.0.10", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/abstract-provider": "^5.0.8", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7" + } + }, + "@ethersproject/address": { + "version": "5.0.9", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/rlp": "^5.0.7" + } + }, + "@ethersproject/base64": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9" + } + }, + "@ethersproject/bignumber": { + "version": "5.0.13", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.0.9", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/constants": { + "version": "5.0.8", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bignumber": "^5.0.13" + } + }, + "@ethersproject/hash": { + "version": "5.0.10", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/abstract-signer": "^5.0.10", + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "@ethersproject/keccak256": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "js-sha3": "0.5.7" + } + }, + "@ethersproject/logger": { + "version": "5.0.8", + "dev": true, + "optional": true + }, + "@ethersproject/networks": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/properties": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/rlp": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/signing-key": { + "version": "5.0.8", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "elliptic": "6.5.3" + } + }, + "@ethersproject/strings": { + "version": "5.0.8", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/transactions": { + "version": "5.0.9", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/rlp": "^5.0.7", + "@ethersproject/signing-key": "^5.0.8" + } + }, + "@ethersproject/web": { + "version": "5.0.12", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/base64": "^5.0.7", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "dev": true, + "optional": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "dev": true, + "optional": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/bn.js": { + "version": "4.11.6", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "14.14.20", + "dev": true + }, + "@types/pbkdf2": { + "version": "3.1.0", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.1", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true + }, + "abstract-leveldown": { + "version": "3.0.0", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "accepts": { + "version": "1.3.7", + "dev": true, + "optional": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "aes-js": { + "version": "3.1.2", + "dev": true, + "optional": true + }, + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-styles": { + "version": "3.2.1", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "arr-diff": { + "version": "4.0.0", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "dev": true, + "optional": true + }, + "array-unique": { + "version": "0.3.2", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "dev": true + }, + "async": { + "version": "2.6.2", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "async-eventemitter": { + "version": "0.2.4", + "dev": true, + "requires": { + "async": "^2.4.0" + } + }, + "async-limiter": { + "version": "1.0.1", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "dev": true + }, + "atob": { + "version": "2.1.2", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "dev": true + } + } + }, + "babel-core": { + "version": "6.26.3", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "json5": { + "version": "0.5.1", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + }, + "slash": { + "version": "1.0.0", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.1", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "dev": true + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-preset-env": { + "version": "1.7.0", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "dev": true + } + } + }, + "babel-register": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + }, + "dependencies": { + "source-map-support": { + "version": "0.4.18", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "babel-types": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "dev": true + } + } + }, + "babelify": { + "version": "7.3.0", + "dev": true, + "requires": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, + "babylon": { + "version": "6.18.0", + "dev": true + }, + "backoff": { + "version": "2.5.0", + "dev": true, + "requires": { + "precond": "0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "dev": true + }, + "base": { + "version": "0.11.2", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "base-x": { + "version": "3.0.8", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "dev": true + } + } + }, + "bignumber.js": { + "version": "9.0.1", + "dev": true, + "optional": true + }, + "bip39": { + "version": "2.5.0", + "dev": true, + "requires": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "blakejs": { + "version": "1.1.0", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "dev": true, + "optional": true + }, + "bn.js": { + "version": "4.11.9", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "dev": true, + "optional": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.7.0", + "dev": true, + "optional": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "dev": true, + "optional": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "dev": true, + "optional": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "5.1.3", + "dev": true, + "optional": true + } + } + }, + "browserify-sign": { + "version": "4.2.1", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "bn.js": { + "version": "5.1.3", + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "3.6.0", + "dev": true, + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "browserslist": { + "version": "3.2.8", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "bs58": { + "version": "4.0.1", + "dev": true, + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "dev": true, + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "5.7.1", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.1", + "dev": true + }, + "buffer-to-arraybuffer": { + "version": "0.0.5", + "dev": true, + "optional": true + }, + "buffer-xor": { + "version": "1.0.3", + "dev": true + }, + "bufferutil": { + "version": "4.0.3", + "dev": true, + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "bytes": { + "version": "3.1.0", + "dev": true, + "optional": true + }, + "bytewise": { + "version": "1.1.0", + "dev": true, + "requires": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "bytewise-core": { + "version": "1.2.3", + "dev": true, + "requires": { + "typewise-core": "^1.2" + } + }, + "cache-base": { + "version": "1.0.1", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cacheable-request": { + "version": "6.1.0", + "dev": true, + "optional": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "lowercase-keys": { + "version": "2.0.0", + "dev": true, + "optional": true + } + } + }, + "cachedown": { + "version": "1.0.0", + "dev": true, + "requires": { + "abstract-leveldown": "^2.4.1", + "lru-cache": "^3.2.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "lru-cache": { + "version": "3.2.0", + "dev": true, + "requires": { + "pseudomap": "^1.0.1" + } + } + } + }, + "call-bind": { + "version": "1.0.2", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caniuse-lite": { + "version": "1.0.30001174", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "checkpoint-store": { + "version": "1.1.0", + "dev": true, + "requires": { + "functional-red-black-tree": "^1.0.1" + } + }, + "chownr": { + "version": "1.1.4", + "dev": true, + "optional": true + }, + "ci-info": { + "version": "2.0.0", + "dev": true + }, + "cids": { + "version": "0.7.5", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "dependencies": { + "multicodec": { + "version": "1.0.4", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + } + } + }, + "cipher-base": { + "version": "1.0.4", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-is": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "class-utils": { + "version": "0.3.6", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "dev": true + } + } + }, + "clone": { + "version": "2.1.2", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "dev": true, + "optional": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "content-disposition": { + "version": "0.5.3", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true, + "optional": true + } + } + }, + "content-hash": { + "version": "2.5.2", + "dev": true, + "optional": true, + "requires": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "content-type": { + "version": "1.0.4", + "dev": true, + "optional": true + }, + "convert-source-map": { + "version": "1.7.0", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "cookie": { + "version": "0.4.0", + "dev": true, + "optional": true + }, + "cookie-signature": { + "version": "1.0.6", + "dev": true, + "optional": true + }, + "cookiejar": { + "version": "2.1.2", + "dev": true, + "optional": true + }, + "copy-descriptor": { + "version": "0.1.1", + "dev": true + }, + "core-js": { + "version": "2.6.12", + "dev": true + }, + "core-js-pure": { + "version": "3.8.2", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "dev": true + }, + "cors": { + "version": "2.8.5", + "dev": true, + "optional": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "create-ecdh": { + "version": "4.0.4", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "create-hash": { + "version": "1.2.0", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-fetch": { + "version": "2.2.3", + "dev": true, + "requires": { + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "dev": true, + "optional": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "d": { + "version": "1.0.1", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.2.6", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "dev": true + }, + "decompress-response": { + "version": "3.3.0", + "dev": true, + "optional": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-equal": { + "version": "1.1.1", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "dev": true, + "optional": true + }, + "deferred-leveldown": { + "version": "4.0.2", + "dev": true, + "requires": { + "abstract-leveldown": "~5.0.0", + "inherits": "^2.0.3" + }, + "dependencies": { + "abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "define-properties": { + "version": "1.1.3", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "defined": { + "version": "1.0.0", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "dev": true + }, + "depd": { + "version": "1.1.2", + "dev": true, + "optional": true + }, + "des.js": { + "version": "1.0.1", + "dev": true, + "optional": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "dev": true, + "optional": true + }, + "detect-indent": { + "version": "4.0.0", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "diffie-hellman": { + "version": "5.0.3", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dom-walk": { + "version": "0.1.2", + "dev": true + }, + "dotignore": { + "version": "0.1.2", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "duplexer3": { + "version": "0.1.4", + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "dev": true, + "optional": true + }, + "electron-to-chromium": { + "version": "1.3.636", + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "encodeurl": { + "version": "1.0.2", + "dev": true, + "optional": true + }, + "encoding": { + "version": "0.1.13", + "dev": true, + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "encoding-down": { + "version": "5.0.4", + "dev": true, + "requires": { + "abstract-leveldown": "^5.0.0", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "xtend": "^4.0.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "end-of-stream": { + "version": "1.4.4", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "errno": { + "version": "0.1.8", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "es-abstract": { + "version": "1.18.0-next.1", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "escape-html": { + "version": "1.0.3", + "dev": true, + "optional": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "dev": true + }, + "etag": { + "version": "1.8.1", + "dev": true, + "optional": true + }, + "eth-block-tracker": { + "version": "3.0.1", + "dev": true, + "requires": { + "eth-query": "^2.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.3", + "ethjs-util": "^0.1.3", + "json-rpc-engine": "^3.6.0", + "pify": "^2.3.0", + "tape": "^4.6.3" + }, + "dependencies": { + "ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "requires": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "pify": { + "version": "2.3.0", + "dev": true + } + } + }, + "eth-ens-namehash": { + "version": "2.0.8", + "dev": true, + "optional": true, + "requires": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "eth-json-rpc-infura": { + "version": "3.2.1", + "dev": true, + "requires": { + "cross-fetch": "^2.1.1", + "eth-json-rpc-middleware": "^1.5.0", + "json-rpc-engine": "^3.4.0", + "json-rpc-error": "^2.0.0" + } + }, + "eth-json-rpc-middleware": { + "version": "1.6.0", + "dev": true, + "requires": { + "async": "^2.5.0", + "eth-query": "^2.1.2", + "eth-tx-summary": "^3.1.2", + "ethereumjs-block": "^1.6.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.2", + "ethereumjs-vm": "^2.1.0", + "fetch-ponyfill": "^4.0.0", + "json-rpc-engine": "^3.6.0", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "tape": "^4.6.3" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "requires": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereum-common": { + "version": "0.2.0", + "dev": true + } + } + }, + "ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "requires": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "requires": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + } + } + }, + "eth-lib": { + "version": "0.1.29", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "eth-query": { + "version": "2.1.2", + "dev": true, + "requires": { + "json-rpc-random-id": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "eth-sig-util": { + "version": "3.0.0", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "elliptic": "^6.4.0", + "ethereumjs-abi": "0.6.5", + "ethereumjs-util": "^5.1.1", + "tweetnacl": "^1.0.0", + "tweetnacl-util": "^0.15.0" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "0.6.5", + "dev": true, + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" + }, + "dependencies": { + "ethereumjs-util": { + "version": "4.5.1", + "dev": true, + "requires": { + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.0.0" + } + } + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "eth-tx-summary": { + "version": "3.2.4", + "dev": true, + "requires": { + "async": "^2.1.2", + "clone": "^2.0.0", + "concat-stream": "^1.5.1", + "end-of-stream": "^1.1.0", + "eth-query": "^2.0.2", + "ethereumjs-block": "^1.4.1", + "ethereumjs-tx": "^1.1.1", + "ethereumjs-util": "^5.0.1", + "ethereumjs-vm": "^2.6.0", + "through2": "^2.0.3" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "requires": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereum-common": { + "version": "0.2.0", + "dev": true + } + } + }, + "ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "requires": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "requires": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + } + } + }, + "ethashjs": { + "version": "0.0.8", + "dev": true, + "requires": { + "async": "^2.1.2", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.0.2", + "miller-rabin": "^4.0.0" + }, + "dependencies": { + "bn.js": { + "version": "5.1.3", + "dev": true + }, + "buffer-xor": { + "version": "2.0.2", + "dev": true, + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-util": { + "version": "7.0.7", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + } + } + } + }, + "ethereum-bloom-filters": { + "version": "1.0.7", + "dev": true, + "optional": true, + "requires": { + "js-sha3": "^0.8.0" + }, + "dependencies": { + "js-sha3": { + "version": "0.8.0", + "dev": true, + "optional": true + } + } + }, + "ethereum-common": { + "version": "0.0.18", + "dev": true + }, + "ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "ethereumjs-account": { + "version": "3.0.0", + "dev": true, + "requires": { + "ethereumjs-util": "^6.0.0", + "rlp": "^2.2.1", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + } + } + }, + "ethereumjs-blockchain": { + "version": "4.0.4", + "dev": true, + "requires": { + "async": "^2.6.1", + "ethashjs": "~0.0.7", + "ethereumjs-block": "~2.2.2", + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.1.0", + "flow-stoplight": "^1.0.0", + "level-mem": "^3.0.1", + "lru-cache": "^5.1.1", + "rlp": "^2.2.2", + "semaphore": "^1.1.0" + } + }, + "ethereumjs-common": { + "version": "1.5.0", + "dev": true + }, + "ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "requires": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "ethereumjs-vm": { + "version": "4.2.0", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "core-js-pure": "^3.0.1", + "ethereumjs-account": "^3.0.0", + "ethereumjs-block": "^2.2.2", + "ethereumjs-blockchain": "^4.0.3", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.2", + "ethereumjs-util": "^6.2.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1", + "util.promisify": "^1.0.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + } + } + }, + "ethereumjs-wallet": { + "version": "0.6.5", + "dev": true, + "optional": true, + "requires": { + "aes-js": "^3.1.1", + "bs58check": "^2.1.2", + "ethereum-cryptography": "^0.1.3", + "ethereumjs-util": "^6.0.0", + "randombytes": "^2.0.6", + "safe-buffer": "^5.1.2", + "scryptsy": "^1.2.1", + "utf8": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "ethjs-unit": { + "version": "0.1.6", + "dev": true, + "optional": true, + "requires": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "dev": true, + "optional": true + } + } + }, + "ethjs-util": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + } + }, + "eventemitter3": { + "version": "4.0.4", + "dev": true, + "optional": true + }, + "events": { + "version": "3.2.0", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "express": { + "version": "4.17.1", + "dev": true, + "optional": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.7.0", + "dev": true, + "optional": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true, + "optional": true + } + } + }, + "ext": { + "version": "1.4.0", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.1.0", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.3.0", + "dev": true + }, + "fake-merkle-patricia-tree": { + "version": "1.0.1", + "dev": true, + "requires": { + "checkpoint-store": "^1.1.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true + }, + "fetch-ponyfill": { + "version": "4.1.0", + "dev": true, + "requires": { + "node-fetch": "~1.7.1" + }, + "dependencies": { + "is-stream": { + "version": "1.1.0", + "dev": true + }, + "node-fetch": { + "version": "1.7.3", + "dev": true, + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true, + "optional": true + } + } + }, + "find-yarn-workspace-root": { + "version": "1.2.1", + "dev": true, + "requires": { + "fs-extra": "^4.0.3", + "micromatch": "^3.1.4" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fs-extra": { + "version": "4.0.3", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "flow-stoplight": { + "version": "1.0.0", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "for-in": { + "version": "1.0.2", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "dev": true, + "optional": true + }, + "fragment-cache": { + "version": "0.2.1", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "dev": true, + "optional": true + }, + "fs-extra": { + "version": "7.0.1", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "dev": true + }, + "get-intrinsic": { + "version": "1.0.2", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stream": { + "version": "5.2.0", + "dev": true, + "optional": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.3", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global": { + "version": "4.4.0", + "dev": true, + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "got": { + "version": "9.6.0", + "dev": true, + "optional": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "get-stream": { + "version": "4.1.0", + "dev": true, + "optional": true, + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "graceful-fs": { + "version": "4.2.4", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "dev": true + }, + "has-symbol-support-x": { + "version": "1.4.2", + "dev": true, + "optional": true + }, + "has-symbols": { + "version": "1.0.1", + "dev": true + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "dev": true, + "optional": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-value": { + "version": "1.0.0", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "hash.js": { + "version": "1.1.7", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "heap": { + "version": "0.2.6", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "home-or-tmp": { + "version": "2.0.0", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "dev": true, + "optional": true + }, + "http-errors": { + "version": "1.7.2", + "dev": true, + "optional": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "dev": true, + "optional": true + } + } + }, + "http-https": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "http-signature": { + "version": "1.2.0", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "idna-uts46-hx": { + "version": "2.3.1", + "dev": true, + "optional": true, + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "dev": true, + "optional": true + } + } + }, + "ieee754": { + "version": "1.2.1", + "dev": true + }, + "immediate": { + "version": "3.2.3", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "ipaddr.js": { + "version": "1.9.1", + "dev": true, + "optional": true + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-arguments": { + "version": "1.1.0", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.2", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-date-object": { + "version": "1.0.2", + "dev": true + }, + "is-descriptor": { + "version": "1.0.2", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-finite": { + "version": "1.1.0", + "dev": true + }, + "is-fn": { + "version": "1.0.0", + "dev": true + }, + "is-function": { + "version": "1.0.2", + "dev": true + }, + "is-hex-prefixed": { + "version": "1.0.0", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "dev": true + }, + "is-object": { + "version": "1.0.2", + "dev": true, + "optional": true + }, + "is-plain-obj": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "is-plain-object": { + "version": "2.0.4", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.1", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-retry-allowed": { + "version": "1.2.0", + "dev": true, + "optional": true + }, + "is-symbol": { + "version": "1.0.3", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "dev": true + }, + "isurl": { + "version": "1.0.0", + "dev": true, + "optional": true, + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "js-sha3": { + "version": "0.5.7", + "dev": true, + "optional": true + }, + "js-tokens": { + "version": "4.0.0", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "dev": true, + "optional": true + }, + "json-rpc-engine": { + "version": "3.8.0", + "dev": true, + "requires": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + }, + "json-rpc-error": { + "version": "2.0.0", + "dev": true, + "requires": { + "inherits": "^2.0.1" + } + }, + "json-rpc-random-id": { + "version": "1.0.1", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keccak": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "keyv": { + "version": "3.1.0", + "dev": true, + "optional": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "kind-of": { + "version": "6.0.3", + "dev": true + }, + "klaw-sync": { + "version": "6.0.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11" + } + }, + "level-codec": { + "version": "9.0.2", + "dev": true, + "requires": { + "buffer": "^5.6.0" + } + }, + "level-errors": { + "version": "2.0.1", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "2.0.3", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.5", + "xtend": "^4.0.0" + } + }, + "level-mem": { + "version": "3.0.1", + "dev": true, + "requires": { + "level-packager": "~4.0.0", + "memdown": "~3.0.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "3.0.0", + "dev": true, + "requires": { + "abstract-leveldown": "~5.0.0", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "level-packager": { + "version": "4.0.1", + "dev": true, + "requires": { + "encoding-down": "~5.0.0", + "levelup": "^3.0.0" + } + }, + "level-post": { + "version": "1.0.7", + "dev": true, + "requires": { + "ltgt": "^2.1.2" + } + }, + "level-sublevel": { + "version": "6.6.4", + "dev": true, + "requires": { + "bytewise": "~1.1.0", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "level-iterator-stream": "^2.0.3", + "ltgt": "~2.1.1", + "pull-defer": "^0.2.2", + "pull-level": "^2.0.3", + "pull-stream": "^3.6.8", + "typewiselite": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "level-ws": { + "version": "1.0.0", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.8", + "xtend": "^4.0.1" + } + }, + "levelup": { + "version": "3.1.1", + "dev": true, + "requires": { + "deferred-leveldown": "~4.0.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~3.0.0", + "xtend": "~4.0.0" + }, + "dependencies": { + "level-iterator-stream": { + "version": "3.0.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "xtend": "^4.0.0" + } + } + } + }, + "lodash": { + "version": "4.17.20", + "dev": true + }, + "looper": { + "version": "2.0.0", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "lru-cache": { + "version": "5.1.1", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "ltgt": { + "version": "2.1.3", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "dev": true, + "optional": true + }, + "merge-descriptors": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "merkle-patricia-tree": { + "version": "3.0.0", + "dev": true, + "requires": { + "async": "^2.6.1", + "ethereumjs-util": "^5.2.0", + "level-mem": "^3.0.1", + "level-ws": "^1.0.0", + "readable-stream": "^3.0.6", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "methods": { + "version": "1.1.2", + "dev": true, + "optional": true + }, + "miller-rabin": { + "version": "4.0.1", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "dev": true, + "optional": true + }, + "mime-db": { + "version": "1.45.0", + "dev": true + }, + "mime-types": { + "version": "2.1.28", + "dev": true, + "requires": { + "mime-db": "1.45.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "min-document": { + "version": "2.19.0", + "dev": true, + "requires": { + "dom-walk": "^0.1.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "dev": true + }, + "minizlib": { + "version": "1.3.3", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "mixin-deep": { + "version": "1.3.2", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + } + }, + "mkdirp": { + "version": "0.5.5", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mkdirp-promise": { + "version": "5.0.1", + "dev": true, + "optional": true, + "requires": { + "mkdirp": "*" + } + }, + "mock-fs": { + "version": "4.13.0", + "dev": true, + "optional": true + }, + "ms": { + "version": "2.1.3", + "dev": true + }, + "multibase": { + "version": "0.6.1", + "dev": true, + "optional": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "multicodec": { + "version": "0.5.7", + "dev": true, + "optional": true, + "requires": { + "varint": "^5.0.0" + } + }, + "multihashes": { + "version": "0.4.21", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + }, + "dependencies": { + "multibase": { + "version": "0.7.0", + "dev": true, + "optional": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + } + } + }, + "nano-json-stream-parser": { + "version": "0.1.2", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "negotiator": { + "version": "0.6.2", + "dev": true, + "optional": true + }, + "next-tick": { + "version": "1.0.0", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "dev": true + }, + "node-addon-api": { + "version": "2.0.2", + "bundled": true, + "dev": true + }, + "node-fetch": { + "version": "2.1.2", + "dev": true + }, + "node-gyp-build": { + "version": "4.2.3", + "bundled": true, + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "dev": true, + "optional": true + }, + "number-to-bn": { + "version": "1.7.0", + "dev": true, + "optional": true, + "requires": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "dev": true, + "optional": true + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.9.0", + "dev": true + }, + "object-is": { + "version": "1.1.4", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.2", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.1", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "object.pick": { + "version": "1.3.0", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "oboe": { + "version": "2.1.4", + "dev": true, + "optional": true, + "requires": { + "http-https": "^1.0.0" + } + }, + "on-finished": { + "version": "2.3.0", + "dev": true, + "optional": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "p-timeout": { + "version": "1.2.1", + "dev": true, + "optional": true, + "requires": { + "p-finally": "^1.0.0" + }, + "dependencies": { + "p-finally": { + "version": "1.0.0", + "dev": true, + "optional": true + } + } + }, + "parse-asn1": { + "version": "5.1.6", + "dev": true, + "optional": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-headers": { + "version": "2.0.3", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "dev": true, + "optional": true + }, + "pascalcase": { + "version": "0.1.1", + "dev": true + }, + "patch-package": { + "version": "6.2.2", + "dev": true, + "requires": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^1.2.1", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "dev": true + }, + "semver": { + "version": "5.7.1", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "dev": true + }, + "slash": { + "version": "2.0.0", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "which": { + "version": "1.3.1", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "path-is-absolute": { + "version": "1.0.1", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "dev": true, + "optional": true + }, + "pbkdf2": { + "version": "3.1.1", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "dev": true + }, + "precond": { + "version": "0.2.3", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "dev": true, + "optional": true + }, + "private": { + "version": "0.1.8", + "dev": true + }, + "process": { + "version": "0.11.10", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "dev": true + }, + "promise-to-callback": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-fn": "^1.0.0", + "set-immediate-shim": "^1.0.1" + } + }, + "proxy-addr": { + "version": "2.0.6", + "dev": true, + "optional": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "dev": true + }, + "psl": { + "version": "1.8.0", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pull-cat": { + "version": "1.1.11", + "dev": true + }, + "pull-defer": { + "version": "0.2.3", + "dev": true + }, + "pull-level": { + "version": "2.0.4", + "dev": true, + "requires": { + "level-post": "^1.0.7", + "pull-cat": "^1.1.9", + "pull-live": "^1.0.1", + "pull-pushable": "^2.0.0", + "pull-stream": "^3.4.0", + "pull-window": "^2.1.4", + "stream-to-pull-stream": "^1.7.1" + } + }, + "pull-live": { + "version": "1.0.1", + "dev": true, + "requires": { + "pull-cat": "^1.1.9", + "pull-stream": "^3.4.0" + } + }, + "pull-pushable": { + "version": "2.2.0", + "dev": true + }, + "pull-stream": { + "version": "3.6.14", + "dev": true + }, + "pull-window": { + "version": "2.1.4", + "dev": true, + "requires": { + "looper": "^2.0.0" + } + }, + "pump": { + "version": "3.0.0", + "dev": true, + "optional": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "dev": true + }, + "qs": { + "version": "6.5.2", + "dev": true + }, + "query-string": { + "version": "5.1.1", + "dev": true, + "optional": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "randombytes": { + "version": "2.1.0", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "dev": true, + "optional": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "dev": true, + "optional": true + }, + "raw-body": { + "version": "2.4.0", + "dev": true, + "optional": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "regenerate": { + "version": "1.4.2", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + }, + "regexpu-core": { + "version": "2.0.0", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "dev": true + } + } + }, + "repeat-element": { + "version": "1.1.3", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.2", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "resolve-url": { + "version": "0.2.1", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "dev": true, + "optional": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "resumer": { + "version": "0.0.0", + "dev": true, + "requires": { + "through": "~2.3.4" + } + }, + "ret": { + "version": "0.1.15", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rlp": { + "version": "2.2.6", + "dev": true, + "requires": { + "bn.js": "^4.11.1" + } + }, + "rustbn.js": { + "version": "0.2.0", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "dev": true + }, + "safe-event-emitter": { + "version": "1.0.1", + "dev": true, + "requires": { + "events": "^3.0.0" + } + }, + "safe-regex": { + "version": "1.1.0", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "dev": true + }, + "scrypt-js": { + "version": "3.0.1", + "dev": true + }, + "scryptsy": { + "version": "1.2.1", + "dev": true, + "optional": true, + "requires": { + "pbkdf2": "^3.0.3" + } + }, + "secp256k1": { + "version": "4.0.2", + "dev": true, + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "seedrandom": { + "version": "3.0.1", + "dev": true + }, + "semaphore": { + "version": "1.1.0", + "dev": true + }, + "send": { + "version": "0.17.1", + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "dev": true, + "optional": true + } + } + }, + "ms": { + "version": "2.1.1", + "dev": true, + "optional": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "dev": true, + "optional": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "servify": { + "version": "0.1.12", + "dev": true, + "optional": true, + "requires": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + } + }, + "set-immediate-shim": { + "version": "1.0.1", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + } + } + }, + "setimmediate": { + "version": "1.0.5", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "dev": true, + "optional": true + }, + "sha.js": { + "version": "2.4.11", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "simple-concat": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "simple-get": { + "version": "2.8.1", + "dev": true, + "optional": true, + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.12", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sshpk": { + "version": "1.16.1", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "dev": true + } + } + }, + "static-extend": { + "version": "0.1.2", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "dev": true + } + } + }, + "statuses": { + "version": "1.5.0", + "dev": true, + "optional": true + }, + "stream-to-pull-stream": { + "version": "1.7.3", + "dev": true, + "requires": { + "looper": "^3.0.0", + "pull-stream": "^3.2.3" + }, + "dependencies": { + "looper": { + "version": "3.0.0", + "dev": true + } + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "string_decoder": { + "version": "1.1.1", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "string.prototype.trim": { + "version": "1.2.3", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "strip-hex-prefix": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "swarm-js": { + "version": "0.1.40", + "dev": true, + "optional": true, + "requires": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "get-stream": { + "version": "3.0.0", + "dev": true, + "optional": true + }, + "got": { + "version": "7.1.0", + "dev": true, + "optional": true, + "requires": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "p-cancelable": { + "version": "0.3.0", + "dev": true, + "optional": true + }, + "prepend-http": { + "version": "1.0.4", + "dev": true, + "optional": true + }, + "url-parse-lax": { + "version": "1.0.0", + "dev": true, + "optional": true, + "requires": { + "prepend-http": "^1.0.1" + } + } + } + }, + "tape": { + "version": "4.13.3", + "dev": true, + "requires": { + "deep-equal": "~1.1.1", + "defined": "~1.0.0", + "dotignore": "~0.1.2", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.6", + "has": "~1.0.3", + "inherits": "~2.0.4", + "is-regex": "~1.0.5", + "minimist": "~1.2.5", + "object-inspect": "~1.7.0", + "resolve": "~1.17.0", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.2.1", + "through": "~2.3.8" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "is-regex": { + "version": "1.0.5", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "tar": { + "version": "4.4.13", + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "dependencies": { + "fs-minipass": { + "version": "1.2.7", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "minipass": { + "version": "2.9.0", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "through": { + "version": "2.3.8", + "dev": true + }, + "through2": { + "version": "2.0.5", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timed-out": { + "version": "4.0.1", + "dev": true, + "optional": true + }, + "tmp": { + "version": "0.1.0", + "dev": true, + "requires": { + "rimraf": "^2.6.3" + } + }, + "to-object-path": { + "version": "0.3.0", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-readable-stream": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "to-regex": { + "version": "3.0.2", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "tough-cookie": { + "version": "2.5.0", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "trim-right": { + "version": "1.0.1", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "dev": true + }, + "tweetnacl-util": { + "version": "0.15.1", + "dev": true + }, + "type": { + "version": "1.2.0", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "dev": true, + "optional": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typewise": { + "version": "1.0.3", + "dev": true, + "requires": { + "typewise-core": "^1.2.0" + } + }, + "typewise-core": { + "version": "1.2.0", + "dev": true + }, + "typewiselite": { + "version": "1.0.0", + "dev": true + }, + "ultron": { + "version": "1.1.1", + "dev": true, + "optional": true + }, + "underscore": { + "version": "1.9.1", + "dev": true, + "optional": true + }, + "union-value": { + "version": "1.0.1", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "dev": true + }, + "unorm": { + "version": "1.6.0", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "unset-value": { + "version": "1.0.0", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "dev": true + } + } + }, + "uri-js": { + "version": "4.4.1", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "dev": true + }, + "url-parse-lax": { + "version": "3.0.0", + "dev": true, + "optional": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "url-set-query": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "url-to-options": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "use": { + "version": "3.1.1", + "dev": true + }, + "utf-8-validate": { + "version": "5.0.4", + "dev": true, + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "utf8": { + "version": "3.0.0", + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "dev": true + }, + "util.promisify": { + "version": "1.1.1", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "for-each": "^0.3.3", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.1" + } + }, + "utils-merge": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "uuid": { + "version": "3.4.0", + "dev": true + }, + "varint": { + "version": "5.0.2", + "dev": true, + "optional": true + }, + "vary": { + "version": "1.1.2", + "dev": true, + "optional": true + }, + "verror": { + "version": "1.10.0", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "web3": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "web3-bzz": "1.2.11", + "web3-core": "1.2.11", + "web3-eth": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-shh": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-bzz": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40", + "underscore": "1.9.1" + }, + "dependencies": { + "@types/node": { + "version": "12.19.12", + "dev": true, + "optional": true + } + } + }, + "web3-core": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-requestmanager": "1.2.11", + "web3-utils": "1.2.11" + }, + "dependencies": { + "@types/node": { + "version": "12.19.12", + "dev": true, + "optional": true + } + } + }, + "web3-core-helpers": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "underscore": "1.9.1", + "web3-eth-iban": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-core-method": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/transactions": "^5.0.0-beta.135", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-core-promievent": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "eventemitter3": "4.0.4" + } + }, + "web3-core-requestmanager": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-providers-http": "1.2.11", + "web3-providers-ipc": "1.2.11", + "web3-providers-ws": "1.2.11" + } + }, + "web3-core-subscriptions": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + } + }, + "web3-eth": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-accounts": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-eth-ens": "1.2.11", + "web3-eth-iban": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-eth-abi": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/abi": "5.0.0-beta.153", + "underscore": "1.9.1", + "web3-utils": "1.2.11" + } + }, + "web3-eth-accounts": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-common": "^1.3.2", + "ethereumjs-tx": "^2.1.1", + "scrypt-js": "^3.0.1", + "underscore": "1.9.1", + "uuid": "3.3.2", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "uuid": { + "version": "3.3.2", + "dev": true, + "optional": true + } + } + }, + "web3-eth-contract": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@types/bn.js": "^4.11.5", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-eth-ens": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-eth-iban": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.9", + "web3-utils": "1.2.11" + } + }, + "web3-eth-personal": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@types/node": "^12.12.6", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + }, + "dependencies": { + "@types/node": { + "version": "12.19.12", + "dev": true, + "optional": true + } + } + }, + "web3-net": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-provider-engine": { + "version": "14.2.1", + "dev": true, + "requires": { + "async": "^2.5.0", + "backoff": "^2.5.0", + "clone": "^2.0.0", + "cross-fetch": "^2.1.0", + "eth-block-tracker": "^3.0.0", + "eth-json-rpc-infura": "^3.1.0", + "eth-sig-util": "^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" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "eth-sig-util": { + "version": "1.4.2", + "dev": true, + "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "ethereumjs-util": "^5.1.1" + } + }, + "ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "requires": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereum-common": { + "version": "0.2.0", + "dev": true + } + } + }, + "ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "requires": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "requires": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + }, + "ws": { + "version": "5.2.2", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "web3-providers-http": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "web3-core-helpers": "1.2.11", + "xhr2-cookies": "1.1.0" + } + }, + "web3-providers-ipc": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "oboe": "2.1.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + } + }, + "web3-providers-ws": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "websocket": "^1.0.31" + } + }, + "web3-shh": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-net": "1.2.11" + } + }, + "web3-utils": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.9.1", + "utf8": "3.0.0" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + } + } + }, + "websocket": { + "version": "1.0.32", + "dev": true, + "requires": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "whatwg-fetch": { + "version": "2.0.4", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "dev": true + }, + "ws": { + "version": "3.3.3", + "dev": true, + "optional": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true, + "optional": true + } + } + }, + "xhr": { + "version": "2.6.0", + "dev": true, + "requires": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xhr-request": { + "version": "1.1.0", + "dev": true, + "optional": true, + "requires": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "xhr-request-promise": { + "version": "0.1.3", + "dev": true, + "optional": true, + "requires": { + "xhr-request": "^1.1.0" + } + }, + "xhr2-cookies": { + "version": "1.1.0", + "dev": true, + "optional": true, + "requires": { + "cookiejar": "^2.1.1" + } + }, + "xtend": { + "version": "4.0.2", + "dev": true + }, + "yaeti": { + "version": "0.0.6", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "dev": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-port": { + "version": "3.2.0", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "getpass": { + "version": "0.1.7", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "ghost-testrpc": { + "version": "0.0.2", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + } + }, + "glob": { + "version": "7.1.6", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global": { + "version": "4.4.0", + "dev": true, + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "global-modules": { + "version": "2.0.0", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "globals": { + "version": "13.12.0", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.0.4", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "dev": true + }, + "growl": { + "version": "1.10.5", + "dev": true + }, + "handlebars": { + "version": "4.7.7", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "hardhat": { + "version": "2.7.0", + "dev": true, + "requires": { + "@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": "^8.3.2", + "ws": "^7.4.6" + }, + "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "semver": { + "version": "6.3.0", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "dev": true + } + } + }, + "hardhat-contract-sizer": { + "version": "2.1.1", + "dev": true, + "requires": { + "cli-table3": "^0.6.0", + "colors": "^1.4.0" + } + }, + "hardhat-gas-reporter": { + "version": "1.0.6", + "dev": true, + "requires": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.23", + "sha1": "^1.1.1" + } + }, + "hardhat-log-remover": { + "version": "2.0.2", + "dev": true, + "requires": {} + }, + "hardhat-spdx-license-identifier": { + "version": "2.0.3", + "dev": true, + "requires": {} + }, + "has": { + "version": "1.0.3", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "dev": true + }, + "has-symbol-support-x": { + "version": "1.4.2", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "dev": true + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "dev": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-tostringtag": { + "version": "1.0.0", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hash-base": { + "version": "3.1.0", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "hash.js": { + "version": "1.1.7", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "dev": true + }, + "http-basic": { + "version": "8.1.3", + "dev": true, + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "dev": true + }, + "http-errors": { + "version": "1.7.3", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-https": { + "version": "1.0.0", + "dev": true + }, + "http-response-object": { + "version": "3.0.2", + "dev": true, + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "dev": true + } + } + }, + "http-signature": { + "version": "1.2.0", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "husky": { + "version": "7.0.4", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "idna-uts46-hx": { + "version": "2.3.1", + "dev": true, + "requires": { + "punycode": "2.1.0" + } + }, + "ieee754": { + "version": "1.2.1", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "dev": true + }, + "immediate": { + "version": "3.3.0", + "dev": true + }, + "immutable": { + "version": "4.0.0", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "dev": true + }, + "ini": { + "version": "1.3.8", + "dev": true + }, + "internal-slot": { + "version": "1.0.3", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "interpret": { + "version": "1.4.0", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "dev": true + }, + "io-ts": { + "version": "1.10.4", + "dev": true, + "requires": { + "fp-ts": "^1.0.0" + } + }, + "ipaddr.js": { + "version": "1.9.1", + "dev": true + }, + "is-arguments": { + "version": "1.1.1", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "dev": true + }, + "is-bigint": { + "version": "1.0.1", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-date-object": { + "version": "1.0.2", + "dev": true + }, + "is-docker": { + "version": "2.2.1", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true + }, + "is-function": { + "version": "1.0.2", + "dev": true + }, + "is-generator-function": { + "version": "1.0.10", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hex-prefixed": { + "version": "1.0.0", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "dev": true + }, + "is-number-object": { + "version": "1.0.4", + "dev": true + }, + "is-object": { + "version": "1.0.2", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-retry-allowed": { + "version": "1.2.0", + "dev": true + }, + "is-shared-array-buffer": { + "version": "1.0.1", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "dev": true + }, + "is-string": { + "version": "1.0.5", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typed-array": { + "version": "1.1.8", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.6", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-string": "^1.0.7", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "is-callable": { + "version": "1.2.4", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-string": { + "version": "1.0.7", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, + "is-typedarray": { + "version": "1.0.0", + "dev": true + }, + "is-url": { + "version": "1.2.4", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "dev": true + }, + "is-weakref": { + "version": "1.0.1", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-wsl": { + "version": "2.2.0", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "dev": true + }, + "isomorphic-unfetch": { + "version": "3.1.0", + "dev": true, + "requires": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, + "isstream": { + "version": "0.1.2", + "dev": true + }, + "isurl": { + "version": "1.0.0", + "dev": true, + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "js-cookie": { + "version": "2.2.1", + "dev": true + }, + "js-sha3": { + "version": "0.8.0", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonschema": { + "version": "1.4.0", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keccak": { + "version": "3.0.1", + "dev": true, + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "keyv": { + "version": "3.1.0", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "kind-of": { + "version": "6.0.3", + "dev": true + }, + "klaw": { + "version": "1.3.1", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "klaw-sync": { + "version": "6.0.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11" + } + }, + "lcid": { + "version": "1.0.0", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "level-codec": { + "version": "9.0.2", + "dev": true, + "requires": { + "buffer": "^5.6.0" + } + }, + "level-concat-iterator": { + "version": "2.0.1", + "dev": true + }, + "level-errors": { + "version": "2.0.1", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "4.0.2", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + } + }, + "level-mem": { + "version": "5.0.1", + "dev": true, + "requires": { + "level-packager": "^5.0.3", + "memdown": "^5.0.0" + } + }, + "level-packager": { + "version": "5.1.1", + "dev": true, + "requires": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + } + }, + "level-supports": { + "version": "1.0.1", + "dev": true, + "requires": { + "xtend": "^4.0.2" + } + }, + "level-ws": { + "version": "2.0.0", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.0", + "xtend": "^4.0.1" + } + }, + "levelup": { + "version": "4.4.0", + "dev": true, + "requires": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "levn": { + "version": "0.4.1", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "dev": true + }, + "lodash.assign": { + "version": "4.2.0", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "dev": true + }, + "log-symbols": { + "version": "3.0.0", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "dev": true + }, + "lru_map": { + "version": "0.3.3", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "dev": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "dev": true + } + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "make-error": { + "version": "1.3.6", + "dev": true + }, + "markdown-table": { + "version": "1.1.3", + "dev": true + }, + "mcl-wasm": { + "version": "0.7.9", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "dev": true + }, + "memdown": { + "version": "5.1.0", + "dev": true, + "requires": { + "abstract-leveldown": "~6.2.1", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "6.2.3", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "immediate": { + "version": "3.2.3", + "dev": true + } + } + }, + "memorystream": { + "version": "0.3.1", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "dev": true + }, + "merkle-patricia-tree": { + "version": "4.2.2", + "dev": true, + "requires": { + "@types/levelup": "^4.3.0", + "ethereumjs-util": "^7.1.2", + "level-mem": "^5.0.1", + "level-ws": "^2.0.0", + "readable-stream": "^3.6.0", + "rlp": "^2.2.4", + "semaphore-async-await": "^1.5.1" + } + }, + "methods": { + "version": "1.1.2", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "miller-rabin": { + "version": "4.0.1", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "dev": true + }, + "mime-db": { + "version": "1.47.0", + "dev": true + }, + "mime-types": { + "version": "2.1.30", + "dev": true, + "requires": { + "mime-db": "1.47.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "dev": true + }, + "min-document": { + "version": "2.19.0", + "dev": true, + "requires": { + "dom-walk": "^0.1.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "dev": true + }, + "minipass": { + "version": "2.9.0", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "dev": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mkdirp-promise": { + "version": "5.0.1", + "dev": true, + "requires": { + "mkdirp": "*" + } + }, + "mnemonist": { + "version": "0.38.5", + "dev": true, + "requires": { + "obliterator": "^2.0.0" + } + }, + "mocha": { + "version": "7.2.0", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "dev": true + }, + "chokidar": { + "version": "3.3.0", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, + "debug": { + "version": "3.2.6", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "3.0.0", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.1.1", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "dev": true + }, + "readdirp": { + "version": "3.2.0", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "dev": true + }, + "supports-color": { + "version": "6.0.0", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "mock-fs": { + "version": "4.14.0", + "dev": true + }, + "ms": { + "version": "2.1.2", + "dev": true + }, + "multibase": { + "version": "0.6.1", + "dev": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "multicodec": { + "version": "0.5.7", + "dev": true, + "requires": { + "varint": "^5.0.0" + } + }, + "multihashes": { + "version": "0.4.21", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + }, + "dependencies": { + "multibase": { + "version": "0.7.0", + "dev": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + } + } + }, + "nan": { + "version": "2.15.0", + "dev": true + }, + "nano-json-stream-parser": { + "version": "0.1.2", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "dev": true + }, + "node-addon-api": { + "version": "2.0.2", + "dev": true + }, + "node-emoji": { + "version": "1.11.0", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, + "node-environment-flags": { + "version": "1.0.6", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "dev": true + } + } + }, + "node-fetch": { + "version": "2.6.1", + "dev": true + }, + "node-gyp-build": { + "version": "4.2.3", + "dev": true + }, + "nofilter": { + "version": "1.0.4", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "dev": true + }, + "number-to-bn": { + "version": "1.7.0", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "dev": true + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "dev": true + }, + "object-inspect": { + "version": "1.9.0", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.3", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "obliterator": { + "version": "2.0.1", + "dev": true + }, + "oboe": { + "version": "2.1.5", + "dev": true, + "requires": { + "http-https": "^1.0.0" + } + }, + "on-finished": { + "version": "2.3.0", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "open": { + "version": "7.4.2", + "dev": true, + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } + }, + "optionator": { + "version": "0.9.1", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-locale": { + "version": "1.4.0", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-timeout": { + "version": "1.2.1", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "dev": true + }, + "parse-headers": { + "version": "2.0.3", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parseurl": { + "version": "1.3.3", + "dev": true + }, + "patch-package": { + "version": "6.4.7", + "dev": true, + "requires": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "dev": true + }, + "slash": { + "version": "2.0.0", + "dev": true + } + } + }, + "path-browserify": { + "version": "1.0.1", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pathval": { + "version": "1.1.1", + "dev": true + }, + "pbkdf2": { + "version": "3.1.2", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "dev": true + }, + "picomatch": { + "version": "2.2.3", + "dev": true + }, + "pify": { + "version": "2.3.0", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "postinstall-postinstall": { + "version": "2.1.0", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "dev": true + }, + "prettier": { + "version": "2.5.0", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "prettier-plugin-solidity": { + "version": "1.0.0-beta.19", + "dev": true, + "requires": { + "@solidity-parser/parser": "^0.14.0", + "emoji-regex": "^10.0.0", + "escape-string-regexp": "^4.0.0", + "semver": "^7.3.5", + "solidity-comments-extractor": "^0.0.7", + "string-width": "^4.2.3" + }, + "dependencies": { + "emoji-regex": { + "version": "10.0.0", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "dev": true + } + } + } + } + }, + "printj": { + "version": "1.1.2", + "dev": true + }, + "process": { + "version": "0.11.10", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "dev": true + }, + "progress": { + "version": "2.0.3", + "dev": true + }, + "promise": { + "version": "8.1.0", + "dev": true, + "requires": { + "asap": "~2.0.6" + } + }, + "proxy-addr": { + "version": "2.0.7", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "dev": true + }, + "psl": { + "version": "1.8.0", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.0", + "dev": true + }, + "qs": { + "version": "6.10.1", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "query-string": { + "version": "5.1.1", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "dev": true + }, + "raw-body": { + "version": "2.4.2", + "dev": true, + "requires": { + "bytes": "3.1.1", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.1", + "dev": true + }, + "http-errors": { + "version": "1.8.1", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "setprototypeof": { + "version": "1.2.0", + "dev": true + }, + "toidentifier": { + "version": "1.0.1", + "dev": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "3.6.0", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.6.2", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "recursive-readdir": { + "version": "2.2.2", + "dev": true, + "requires": { + "minimatch": "3.0.4" + } + }, + "regexpp": { + "version": "3.2.0", + "dev": true + }, + "req-cwd": { + "version": "2.0.0", + "dev": true, + "requires": { + "req-from": "^2.0.0" + } + }, + "req-from": { + "version": "2.0.0", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "dev": true + } + } + }, + "request": { + "version": "2.88.2", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "qs": { + "version": "6.5.2", + "dev": true + } + } + }, + "request-promise-core": { + "version": "1.1.4", + "dev": true, + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "reusify": { + "version": "1.0.4", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rlp": { + "version": "2.2.6", + "dev": true, + "requires": { + "bn.js": "^4.11.1" + } + }, + "run-parallel": { + "version": "1.2.0", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rustbn.js": { + "version": "0.2.0", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "dev": true + }, + "sc-istanbul": { + "version": "0.4.6", + "dev": true, + "requires": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + }, + "esprima": { + "version": "2.7.3", + "dev": true + }, + "glob": { + "version": "5.0.15", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "1.0.0", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "scrypt-js": { + "version": "3.0.1", + "dev": true + }, + "secp256k1": { + "version": "4.0.2", + "dev": true, + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "semaphore-async-await": { + "version": "1.5.1", + "dev": true + }, + "semver": { + "version": "7.3.5", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.17.1", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "servify": { + "version": "0.1.12", + "dev": true, + "requires": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + } + }, + "set-blocking": { + "version": "2.0.0", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "sha1": { + "version": "1.1.1", + "dev": true, + "requires": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "dev": true + }, + "shelljs": { + "version": "0.8.4", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "side-channel": { + "version": "1.0.4", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "simple-concat": { + "version": "1.0.1", + "dev": true + }, + "simple-get": { + "version": "2.8.1", + "dev": true, + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "slash": { + "version": "3.0.0", + "dev": true + }, + "solc": { + "version": "0.7.3", + "dev": true, + "requires": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "dependencies": { + "follow-redirects": { + "version": "1.14.5", + "dev": true + }, + "fs-extra": { + "version": "0.30.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "jsonfile": { + "version": "2.4.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "semver": { + "version": "5.7.1", + "dev": true + } + } + }, + "solidity-comments-extractor": { + "version": "0.0.7", + "dev": true + }, + "solidity-coverage": { + "version": "0.7.17", + "dev": true, + "requires": { + "@solidity-parser/parser": "^0.13.2", + "@truffle/provider": "^0.2.24", + "chalk": "^2.4.2", + "death": "^1.1.0", + "detect-port": "^1.3.0", + "fs-extra": "^8.1.0", + "ganache-cli": "^6.12.2", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.15", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.0" + }, + "dependencies": { + "@solidity-parser/parser": { + "version": "0.13.2", + "dev": true, + "requires": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "fs-extra": { + "version": "8.1.0", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "globby": { + "version": "10.0.2", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "pify": { + "version": "4.0.1", + "dev": true + } + } + }, + "source-map": { + "version": "0.6.1", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdx-correct": { + "version": "3.1.1", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.9", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "dev": true + } + } + }, + "stacktrace-parser": { + "version": "0.1.10", + "dev": true, + "requires": { + "type-fest": "^0.7.1" + }, + "dependencies": { + "type-fest": { + "version": "0.7.1", + "dev": true + } + } + }, + "statuses": { + "version": "1.5.0", + "dev": true + }, + "stealthy-require": { + "version": "1.1.1", + "dev": true + }, + "strict-uri-encode": { + "version": "1.1.0", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "string-width": { + "version": "2.1.1", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "6.0.1", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-hex-prefix": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "swarm-js": { + "version": "0.1.40", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + }, + "dependencies": { + "eth-lib": { + "version": "0.1.29", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "fs-extra": { + "version": "4.0.3", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "get-stream": { + "version": "3.0.0", + "dev": true + }, + "got": { + "version": "7.1.0", + "dev": true, + "requires": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + } + }, + "p-cancelable": { + "version": "0.3.0", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "url-parse-lax": { + "version": "1.0.0", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "ws": { + "version": "3.3.3", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "sync-request": { + "version": "6.1.0", + "dev": true, + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "dev": true, + "requires": { + "get-port": "^3.1.0" + } + }, + "tar": { + "version": "4.4.19", + "dev": true, + "requires": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + } + }, + "test-value": { + "version": "2.1.0", + "dev": true, + "requires": { + "array-back": "^1.0.3", + "typical": "^2.6.0" + }, + "dependencies": { + "array-back": { + "version": "1.0.4", + "dev": true, + "requires": { + "typical": "^2.6.0" + } + } + } + }, + "testrpc": { + "version": "0.0.1", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "dev": true + }, + "then-request": { + "version": "6.0.2", + "dev": true, + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "dev": true + }, + "form-data": { + "version": "2.5.1", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } + } + }, + "timed-out": { + "version": "4.0.1", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "dev": true + } + } + }, + "true-case-path": { + "version": "2.2.1", + "dev": true + }, + "ts-essentials": { + "version": "1.0.4", + "dev": true + }, + "ts-generator": { + "version": "0.1.1", + "dev": true, + "requires": { + "@types/mkdirp": "^0.5.2", + "@types/prettier": "^2.1.1", + "@types/resolve": "^0.0.8", + "chalk": "^2.4.1", + "glob": "^7.1.2", + "mkdirp": "^0.5.1", + "prettier": "^2.1.2", + "resolve": "^1.8.1", + "ts-essentials": "^1.0.0" + } + }, + "ts-node": { + "version": "10.4.0", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.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", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "dev": true + } + } + }, + "tslib": { + "version": "1.14.1", + "dev": true + }, + "tsort": { + "version": "0.0.1", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "dev": true + }, + "tweetnacl-util": { + "version": "0.15.1", + "dev": true + }, + "type": { + "version": "1.2.0", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "dev": true + }, + "type-fest": { + "version": "0.20.2", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typechain": { + "version": "6.0.5", + "dev": true, + "requires": { + "@types/prettier": "^2.1.1", + "command-line-args": "^4.0.7", + "debug": "^4.1.1", + "fs-extra": "^7.0.0", + "glob": "^7.1.6", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.1.2", + "ts-essentials": "^7.0.1" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "dev": true + }, + "ts-essentials": { + "version": "7.0.3", + "dev": true, + "requires": {} + } + } + }, + "typedarray": { + "version": "0.0.6", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.5.2", + "dev": true + }, + "typical": { + "version": "2.6.1", + "dev": true + }, + "uglify-js": { + "version": "3.14.2", + "dev": true, + "optional": true + }, + "ultron": { + "version": "1.1.1", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "underscore": { + "version": "1.9.1", + "dev": true + }, + "unfetch": { + "version": "4.2.0", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url": { + "version": "0.11.0", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "dev": true + } + } + }, + "url-parse-lax": { + "version": "3.0.0", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "url-set-query": { + "version": "1.0.0", + "dev": true + }, + "url-to-options": { + "version": "1.0.1", + "dev": true + }, + "utf-8-validate": { + "version": "5.0.6", + "dev": true, + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "utf8": { + "version": "3.0.0", + "dev": true + }, + "util": { + "version": "0.12.4", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "varint": { + "version": "5.0.2", + "dev": true + }, + "vary": { + "version": "1.1.2", + "dev": true + }, + "verror": { + "version": "1.10.0", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "web3": { + "version": "1.5.3", + "dev": true, + "requires": { + "web3-bzz": "1.5.3", + "web3-core": "1.5.3", + "web3-eth": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-shh": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-bzz": { + "version": "1.5.3", + "dev": true, + "requires": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40" + }, + "dependencies": { + "@types/node": { + "version": "12.20.27", + "dev": true + } + } + }, + "web3-core": { + "version": "1.5.3", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-requestmanager": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "@types/node": { + "version": "12.20.27", + "dev": true + }, + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-core-helpers": { + "version": "1.5.3", + "dev": true, + "requires": { + "web3-eth-iban": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-core-method": { + "version": "1.5.3", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.4.0", + "@ethersproject/transactions": "^5.0.0-beta.135", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-core-promievent": { + "version": "1.5.3", + "dev": true, + "requires": { + "eventemitter3": "4.0.4" + } + }, + "web3-core-requestmanager": { + "version": "1.5.3", + "dev": true, + "requires": { + "util": "^0.12.0", + "web3-core-helpers": "1.5.3", + "web3-providers-http": "1.5.3", + "web3-providers-ipc": "1.5.3", + "web3-providers-ws": "1.5.3" + } + }, + "web3-core-subscriptions": { + "version": "1.5.3", + "dev": true, + "requires": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3" + } + }, + "web3-eth": { + "version": "1.5.3", + "dev": true, + "requires": { + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-accounts": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-eth-ens": "1.5.3", + "web3-eth-iban": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-abi": { + "version": "1.5.3", + "dev": true, + "requires": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.5.3" + }, + "dependencies": { + "@ethersproject/abi": { + "version": "5.0.7", + "dev": true, + "requires": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-accounts": { + "version": "1.5.3", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.3.0", + "@ethereumjs/tx": "^3.2.1", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "5.2.0", + "dev": true + }, + "ethereumjs-util": { + "version": "7.1.1", + "dev": true, + "requires": { + "@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" + } + }, + "uuid": { + "version": "3.3.2", + "dev": true + }, + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "dev": true + } + } + } + } + }, + "web3-eth-contract": { + "version": "1.5.3", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.5", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-ens": { + "version": "1.5.3", + "dev": true, + "requires": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-iban": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "web3-utils": "1.5.3" + }, + "dependencies": { + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-personal": { + "version": "1.5.3", + "dev": true, + "requires": { + "@types/node": "^12.12.6", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "@types/node": { + "version": "12.20.27", + "dev": true + }, + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-net": { + "version": "1.5.3", + "dev": true, + "requires": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "web3-utils": { + "version": "1.5.3", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-providers-http": { + "version": "1.5.3", + "dev": true, + "requires": { + "web3-core-helpers": "1.5.3", + "xhr2-cookies": "1.1.0" + } + }, + "web3-providers-ipc": { + "version": "1.5.3", + "dev": true, + "requires": { + "oboe": "2.1.5", + "web3-core-helpers": "1.5.3" + } + }, + "web3-providers-ws": { + "version": "1.5.3", + "dev": true, + "requires": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3", + "websocket": "^1.0.32" + } + }, + "web3-shh": { + "version": "1.5.3", + "dev": true, + "requires": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-net": "1.5.3" + } + }, + "web3-utils": { + "version": "1.3.5", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.9.1", + "utf8": "3.0.0" + } + }, + "websocket": { + "version": "1.0.34", + "dev": true, + "requires": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "dev": true + }, + "which-typed-array": { + "version": "1.1.7", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.7" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.6", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-string": "^1.0.7", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "is-callable": { + "version": "1.2.4", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-string": { + "version": "1.0.7", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, + "wide-align": { + "version": "1.1.3", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "0.2.0", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "dev": true + }, + "ws": { + "version": "7.4.6", + "dev": true, + "requires": {} + }, + "xhr": { + "version": "2.6.0", + "dev": true, + "requires": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xhr-request": { + "version": "1.1.0", + "dev": true, + "requires": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "xhr-request-promise": { + "version": "0.1.3", + "dev": true, + "requires": { + "xhr-request": "^1.1.0" + } + }, + "xhr2-cookies": { + "version": "1.1.0", + "dev": true, + "requires": { + "cookiejar": "^2.1.1" + } + }, + "xmlhttprequest": { + "version": "1.8.0", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "dev": true + }, + "y18n": { + "version": "4.0.3", + "dev": true + }, + "yaeti": { + "version": "0.0.6", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + }, + "yn": { + "version": "3.1.1", + "dev": true + } + } +} diff --git a/lens-protocol/core/package.json b/lens-protocol/core/package.json new file mode 100644 index 0000000..9c39f5e --- /dev/null +++ b/lens-protocol/core/package.json @@ -0,0 +1,98 @@ +{ + "name": "@aave/lens-protocol", + "version": "1.0.2", + "description": "Composable and decentralized social graph", + "main": "index.js", + "scripts": { + "test": "npm run compile && TRACK_GAS=true hardhat test", + "quick-test": "hardhat test", + "spdx": "hardhat prepend-spdx-license", + "size": "npm run compile && hardhat size-contracts", + "full-deploy-local": "hardhat full-deploy --network localhost", + "full-deploy-mumbai": "hardhat full-deploy --network mumbai", + "coverage": "npm run compile && hardhat coverage --temp temp-artifacts --testfiles test/emptyrun.coverage.ts && hardhat coverage --temp temp-artifacts --testfiles '!test/emptyrun.coverage.ts'", + "run-env": "npm i && tail -f /dev/null", + "hardhat": "hardhat", + "hardhat:kovan": "hardhat --network kovan", + "hardhat:tenderly-main": "hardhat --network tenderlyMain", + "hardhat:ropsten": "hardhat --network ropsten", + "hardhat:main": "hardhat --network main", + "hardhat:docker": "hardhat --network hardhatevm_docker", + "hardhat:mumbai": "hardhat --network mumbai", + "hardhat:matic": "hardhat --network matic", + "compile": "SKIP_LOAD=true hardhat clean && SKIP_LOAD=true hardhat compile", + "console:fork": "MAINNET_FORK=true hardhat console", + "format": "prettier --write .", + "lint": "eslint ." + }, + "repository": { + "type": "git", + "url": "https://github.com/aave/lens-protocol" + }, + "bugs": { + "url": "https://github.com/aave/lens-protocol/issues" + }, + "homepage": "https://github.com/aave/lens-protocol#readme", + "devDependencies": { + "@nomiclabs/hardhat-ethers": "2.0.2", + "@nomiclabs/hardhat-etherscan": "2.1.8", + "@typechain/ethers-v5": "8.0.5", + "@typechain/hardhat": "3.0.0", + "@types/chai": "4.2.22", + "@types/mocha": "9.0.0", + "@types/node": "16.11.11", + "@typescript-eslint/eslint-plugin": "5.5.0", + "@typescript-eslint/parser": "5.5.0", + "chai": "4.3.4", + "defender-relay-client": "1.12.1", + "dotenv": "10.0.0", + "eslint": "8.3.0", + "eslint-config-prettier": "8.3.0", + "eslint-plugin-prettier": "4.0.0", + "ethereum-waffle": "3.4.0", + "ethers": "5.5.1", + "hardhat": "2.7.0", + "hardhat-contract-sizer": "2.1.1", + "hardhat-gas-reporter": "1.0.6", + "hardhat-log-remover": "2.0.2", + "hardhat-spdx-license-identifier": "2.0.3", + "husky": "7.0.4", + "prettier": "2.5.0", + "prettier-plugin-solidity": "1.0.0-beta.19", + "solidity-coverage": "0.7.17", + "ts-generator": "0.1.1", + "ts-node": "10.4.0", + "typechain": "6.0.5", + "typescript": "4.5.2" + }, + "husky": { + "hooks": { + "pre-commit": "pretty-quick --staged --pattern 'contracts/**/*.sol' --pattern 'helpers/**/*.ts' --pattern 'test/**/*.ts' --pattern 'tasks/**/*.ts'" + } + }, + "dependencies": { + "@openzeppelin/contracts": "4.5.0" + }, + "author": "Lens", + "contributors": [ + "Peter Michael (Zer0dot)", + "Miguel Martinez", + "Lasse Herskind", + "Steven Valeri", + "Alan Donoso Naumczuk", + "Emilio Frangella", + "David Racero" + ], + "license": "MIT", + "keywords": [ + "lens", + "protocol", + "aave", + "social", + "graph", + "solidity", + "evm", + "contracts", + "core" + ] +} diff --git a/lens-protocol/core/tasks/deploy-access-control.ts b/lens-protocol/core/tasks/deploy-access-control.ts new file mode 100644 index 0000000..0c8555b --- /dev/null +++ b/lens-protocol/core/tasks/deploy-access-control.ts @@ -0,0 +1,197 @@ +import '@nomiclabs/hardhat-ethers'; +import { BigNumber } from 'ethers'; +import { formatEther } from 'ethers/lib/utils'; +import fs from 'fs'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { TransparentUpgradeableProxy__factory, AccessControlV2__factory } from '../typechain-types'; +import { deployContract, deployWithVerify } from './helpers/utils'; + +const LENS_HUB_SANDBOX = '0x7582177F9E536aB0b6c721e11f383C326F2Ad1D5'; +const LENS_HUB_MUMBAI = '0x60Ae865ee4C725cd04353b5AAb364553f56ceF82'; +const LENS_HUB_POLYGON = '0xDb46d1Dc155634FbC732f92E853b10B288AD5a1d'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +task('deploy-access-control', 'deploys the Access Control contract with explorer verification') + .addOptionalParam('lenshubaddress', 'Address of the LensHub proxy') + .addOptionalParam('proxyadmin', 'Address of the Access Control proxy admin to set') + .addOptionalParam('networkfork', 'Network to mimic on local fork') + .addFlag('broadcast', 'Submit transactions on-chain (will run a dry-run without this flag)') + .addFlag('onlyimpl', 'Deploy only the implementation, without proxy (for upgrades)') + .addFlag('upgrade', 'Perform an upgrade instead of deploying from scratch') + .setAction( + async ({ lenshubaddress, proxyadmin, networkfork, broadcast, onlyimpl, upgrade }, hre) => { + // Note that the use of these signers is a placeholder and is not meant to be used in + // production. + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + // const governance = accounts[1]; + const proxyAdminAddress = proxyadmin ?? deployer.address; + + // Setting Lens Hub address if left undefined + if (!lenshubaddress) + switch (hre.network.name) { + case 'matic': + lenshubaddress = LENS_HUB_POLYGON; + break; + case 'mumbai': + lenshubaddress = LENS_HUB_MUMBAI; + break; + case 'sandbox': + lenshubaddress = LENS_HUB_SANDBOX; + break; + case 'local': + switch (networkfork) { + case 'matic': + lenshubaddress = LENS_HUB_POLYGON; + break; + case 'mumbai': + lenshubaddress = LENS_HUB_MUMBAI; + break; + case 'sandbox': + lenshubaddress = LENS_HUB_SANDBOX; + break; + default: + console.log( + '\n\tWhen testing on local fork you need to specify networkFork argument (matic/mumbai/sandbox)', + '\n\t === HALTING DEPLOYMENT ===' + ); + process.exit(); + } + break; + default: + console.log( + '\n\tUnsupported network:', + hre.network.name, + '\n\t === HALTING DEPLOYMENT ===' + ); + process.exit(); + } + + console.log(`\n\tNetwork: ${hre.network.name}`); + console.log(`\n\tDeployer:`, deployer.address); + console.log( + `\n\tDeployer balance:`, + formatEther(await ethers.provider.getBalance(deployer.address)) + ); + console.log(`\n\tproxyAdminAddress:`, proxyAdminAddress); + console.log(`\n\tlenshubaddress:`, lenshubaddress); + + let proxyAddress; + let addresses; + if (!upgrade && !onlyimpl) { + console.log(`\n\n\t Deployment mode: Proxy + Implementation`); + } else { + try { + addresses = JSON.parse(fs.readFileSync('addresses.json', 'utf-8')); + } catch (err) { + console.error( + '\nERROR: No addresses.json found. It is required to fetch existing Proxy address' + ); + process.exit(); + } + proxyAddress = addresses['accessControl proxy']; + if (proxyAddress == undefined || proxyAddress.length != 42) { + console.error('\nERROR: Proxy address not found or invalid'); + process.exit(); + } + if ( + (await ethers.provider.getCode(proxyAddress)).length <= 2 || + (await ethers.provider.getCode(proxyAddress)) == '0x' + ) { + console.error('\nERROR Proxy address is not a contract (doesnt have code)'); + process.exit(); + } + console.log('\n\tAccess Control Proxy found:', proxyAddress); + } + + if (broadcast) { + console.log('\n\t-- Deploying Access Control Implementation --'); + const accessControlImpl = + hre.network.name == 'local' + ? await deployContract(new AccessControlV2__factory(deployer).deploy(lenshubaddress)) + : await deployWithVerify( + new AccessControlV2__factory(deployer).deploy(lenshubaddress), + [lenshubaddress], + 'contracts/misc/AccessControlV2.sol:AccessControlV2' + ); + + const data = accessControlImpl.interface.encodeFunctionData('initialize', []); + + let proxy; + if (!upgrade && !onlyimpl) { + console.log('\n\t-- Deploying Access Control Proxy --'); + proxy = + hre.network.name == 'local' + ? await deployContract( + new TransparentUpgradeableProxy__factory(deployer).deploy( + accessControlImpl.address, + proxyAdminAddress, + data + ) + ) + : await deployWithVerify( + new TransparentUpgradeableProxy__factory(deployer).deploy( + accessControlImpl.address, + proxyAdminAddress, + data + ), + [accessControlImpl.address, deployer.address, data], + 'contracts/upgradeability/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy' + ); + } + + const accessControl = AccessControlV2__factory.connect( + proxy ? proxy.address : proxyAddress, + deployer + ); + + // Save and log the addresses + const addrs = addresses ?? {}; + addrs['accessControl proxy'] = accessControl.address; + addrs['accessControl impl'] = accessControlImpl.address; + const json = JSON.stringify(addrs, null, 2); + console.log(json); + + fs.writeFileSync('addresses.json', json, 'utf-8'); + + if (upgrade) { + const currentAdminRaw = await ethers.provider.getStorageAt( + proxyAddress, + '0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103' + ); + + const currentAdmin = '0x' + currentAdminRaw.slice(-40); + + if (currentAdmin.toLowerCase() != deployer.address.toLowerCase()) { + console.log('\n\t-- Current Proxy Admin is different than deployer --'); + console.log('\tCurrent admin:', currentAdmin.toLowerCase()); + console.log('\tDeployer:', deployer.address.toLowerCase()); + } + + console.log('\n\t-- Trying to perform an upgrade (with the deployer) --'); + + console.log( + 'Previous revision:', + BigNumber.from(await ethers.provider.getStorageAt(accessControl.address, 0)).toString() + ); + + proxy = TransparentUpgradeableProxy__factory.connect(proxyAddress, deployer); + const tx = await proxy.upgradeToAndCall(accessControlImpl.address, data); + await tx.wait(3); + + console.log('\n\t Looks like the upgrade succeeded!'); + + console.log( + 'Revision after upgrade:', + BigNumber.from(await ethers.provider.getStorageAt(accessControl.address, 0)).toString() + ); + } + } else { + console.log('\n--- To broadcast transactions on-chain: add --broadcast flag\n'); + } + } + ); diff --git a/lens-protocol/core/tasks/full-deploy-verify.ts b/lens-protocol/core/tasks/full-deploy-verify.ts new file mode 100644 index 0000000..43bd907 --- /dev/null +++ b/lens-protocol/core/tasks/full-deploy-verify.ts @@ -0,0 +1,381 @@ +import '@nomiclabs/hardhat-ethers'; +import { hexlify, keccak256, RLP } from 'ethers/lib/utils'; +import fs from 'fs'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { + LensHub__factory, + ApprovalFollowModule__factory, + CollectNFT__factory, + FreeCollectModule__factory, + FeeCollectModule__factory, + FeeFollowModule__factory, + FollowerOnlyReferenceModule__factory, + FollowNFT__factory, + InteractionLogic__factory, + LimitedFeeCollectModule__factory, + LimitedTimedFeeCollectModule__factory, + ModuleGlobals__factory, + PublishingLogic__factory, + RevertCollectModule__factory, + TimedFeeCollectModule__factory, + TransparentUpgradeableProxy__factory, + ProfileTokenURILogic__factory, + LensPeriphery__factory, + UIDataProvider__factory, + ProfileFollowModule__factory, + RevertFollowModule__factory, + ProfileCreationProxy__factory, +} from '../typechain-types'; +import { deployWithVerify, waitForTx } from './helpers/utils'; + +const TREASURY_FEE_BPS = 50; +const LENS_HUB_NFT_NAME = 'Lens Protocol Profiles'; +const LENS_HUB_NFT_SYMBOL = 'LPP'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +/** + * @dev Note that this script uses the default ethers signers. + * Care should be taken to also ensure that the following addresses end up properly set: + * 1. LensHub Proxy Admin + * 2. LensHub Governance + * 3. ModuleGlobals Governance + * 3. ModuleGlobals Treasury + * + * Furthermore, This script does not whitelist profile creators or deploy a profile creation + * proxy or a unique currency contract. This also does not whitelist any currencies in the + * ModuleGlobals contract. + */ +task('full-deploy-verify', 'deploys the entire Lens Protocol with explorer verification').setAction( + async ({}, hre) => { + // Note that the use of these signers is a placeholder and is not meant to be used in + // production. + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + const treasuryAddress = accounts[2].address; + const proxyAdminAddress = deployer.address; + const profileCreatorAddress = deployer.address; + + // Nonce management in case of deployment issues + let deployerNonce = await ethers.provider.getTransactionCount(deployer.address); + + console.log('\n\t-- Deploying Module Globals --'); + const moduleGlobals = await deployWithVerify( + new ModuleGlobals__factory(deployer).deploy( + governance.address, + treasuryAddress, + TREASURY_FEE_BPS, + { nonce: deployerNonce++ } + ), + [governance.address, treasuryAddress, TREASURY_FEE_BPS], + 'contracts/core/modules/ModuleGlobals.sol:ModuleGlobals' + ); + + console.log('\n\t-- Deploying Logic Libs --'); + + const publishingLogic = await deployWithVerify( + new PublishingLogic__factory(deployer).deploy({ nonce: deployerNonce++ }), + [], + 'contracts/libraries/PublishingLogic.sol:PublishingLogic' + ); + const interactionLogic = await deployWithVerify( + new InteractionLogic__factory(deployer).deploy({ nonce: deployerNonce++ }), + [], + 'contracts/libraries/InteractionLogic.sol:InteractionLogic' + ); + const profileTokenURILogic = await deployWithVerify( + new ProfileTokenURILogic__factory(deployer).deploy({ nonce: deployerNonce++ }), + [], + 'contracts/libraries/ProfileTokenURILogic.sol:ProfileTokenURILogic' + ); + const hubLibs = { + 'contracts/libraries/PublishingLogic.sol:PublishingLogic': publishingLogic.address, + 'contracts/libraries/InteractionLogic.sol:InteractionLogic': interactionLogic.address, + 'contracts/libraries/ProfileTokenURILogic.sol:ProfileTokenURILogic': + profileTokenURILogic.address, + }; + + // Here, we pre-compute the nonces and addresses used to deploy the contracts. + // const nonce = await deployer.getTransactionCount(); + const followNFTNonce = hexlify(deployerNonce + 1); + const collectNFTNonce = hexlify(deployerNonce + 2); + const hubProxyNonce = hexlify(deployerNonce + 3); + + const followNFTImplAddress = + '0x' + keccak256(RLP.encode([deployer.address, followNFTNonce])).substr(26); + const collectNFTImplAddress = + '0x' + keccak256(RLP.encode([deployer.address, collectNFTNonce])).substr(26); + const hubProxyAddress = + '0x' + keccak256(RLP.encode([deployer.address, hubProxyNonce])).substr(26); + + // Next, we deploy first the hub implementation, then the followNFT implementation, the collectNFT, and finally the + // hub proxy with initialization. + console.log('\n\t-- Deploying Hub Implementation --'); + + const lensHubImpl = await deployWithVerify( + new LensHub__factory(hubLibs, deployer).deploy(followNFTImplAddress, collectNFTImplAddress, { + nonce: deployerNonce++, + }), + [followNFTImplAddress, collectNFTImplAddress], + 'contracts/core/LensHub.sol:LensHub' + ); + + console.log('\n\t-- Deploying Follow & Collect NFT Implementations --'); + await deployWithVerify( + new FollowNFT__factory(deployer).deploy(hubProxyAddress, { nonce: deployerNonce++ }), + [hubProxyAddress], + 'contracts/core/FollowNFT.sol:FollowNFT' + ); + await deployWithVerify( + new CollectNFT__factory(deployer).deploy(hubProxyAddress, { nonce: deployerNonce++ }), + [hubProxyAddress], + 'contracts/core/CollectNFT.sol:CollectNFT' + ); + + let data = lensHubImpl.interface.encodeFunctionData('initialize', [ + LENS_HUB_NFT_NAME, + LENS_HUB_NFT_SYMBOL, + governance.address, + ]); + + console.log('\n\t-- Deploying Hub Proxy --'); + let proxy = await deployWithVerify( + new TransparentUpgradeableProxy__factory(deployer).deploy( + lensHubImpl.address, + proxyAdminAddress, + data, + { nonce: deployerNonce++ } + ), + [lensHubImpl.address, deployer.address, data], + 'contracts/upgradeability/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy' + ); + + // Connect the hub proxy to the LensHub factory and the governance for ease of use. + const lensHub = LensHub__factory.connect(proxy.address, governance); + + console.log('\n\t-- Deploying Lens Periphery --'); + const lensPeriphery = await deployWithVerify( + new LensPeriphery__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/misc/LensPeriphery.sol:LensPeriphery' + ); + + // Deploy collect modules + console.log('\n\t-- Deploying feeCollectModule --'); + const feeCollectModule = await deployWithVerify( + new FeeCollectModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/collect/FeeCollectModule.sol:FeeCollectModule' + ); + console.log('\n\t-- Deploying limitedFeeCollectModule --'); + const limitedFeeCollectModule = await deployWithVerify( + new LimitedFeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address, + { + nonce: deployerNonce++, + } + ), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/collect/LimitedFeeCollectModule.sol:LimitedFeeCollectModule' + ); + console.log('\n\t-- Deploying timedFeeCollectModule --'); + const timedFeeCollectModule = await deployWithVerify( + new TimedFeeCollectModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/collect/TimedFeeCollectModule.sol:TimedFeeCollectModule' + ); + console.log('\n\t-- Deploying limitedTimedFeeCollectModule --'); + const limitedTimedFeeCollectModule = await deployWithVerify( + new LimitedTimedFeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address, + { nonce: deployerNonce++ } + ), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/collect/LimitedTimedFeeCollectModule.sol:LimitedTimedFeeCollectModule' + ); + + console.log('\n\t-- Deploying revertCollectModule --'); + const revertCollectModule = await deployWithVerify( + new RevertCollectModule__factory(deployer).deploy({ nonce: deployerNonce++ }), + [], + 'contracts/core/modules/collect/RevertCollectModule.sol:RevertCollectModule' + ); + console.log('\n\t-- Deploying freeCollectModule --'); + const freeCollectModule = await deployWithVerify( + new FreeCollectModule__factory(deployer).deploy(lensHub.address, { nonce: deployerNonce++ }), + [lensHub.address], + 'contracts/core/modules/collect/FreeCollectModule.sol:FreeCollectModule' + ); + + // Deploy follow modules + console.log('\n\t-- Deploying feeFollowModule --'); + const feeFollowModule = await deployWithVerify( + new FeeFollowModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/follow/FeeFollowModule.sol:FeeFollowModule' + ); + console.log('\n\t-- Deploying profileFollowModule --'); + const profileFollowModule = await deployWithVerify( + new ProfileFollowModule__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/core/modules/follow/ProfileFollowModule.sol:ProfileFollowModule' + ); + console.log('\n\t-- Deploying revertFollowModule --'); + const revertFollowModule = await deployWithVerify( + new RevertFollowModule__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/core/modules/follow/RevertFollowModule.sol:RevertFollowModule' + ); + // --- COMMENTED OUT AS THIS IS NOT A LAUNCH MODULE --- + // console.log('\n\t-- Deploying approvalFollowModule --'); + // const approvalFollowModule = await deployWithVerify( + // new ApprovalFollowModule__factory(deployer).deploy(lensHub.address, { + // nonce: deployerNonce++, + // }), + // [lensHub.address], + // 'contracts/core/modules/follow/ApprovalFollowModule.sol:ApprovalFollowModule' + // ); + + // Deploy reference module + console.log('\n\t-- Deploying followerOnlyReferenceModule --'); + const followerOnlyReferenceModule = await deployWithVerify( + new FollowerOnlyReferenceModule__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/core/modules/reference/FollowerOnlyReferenceModule.sol:FollowerOnlyReferenceModule' + ); + + // Deploy UIDataProvider + console.log('\n\t-- Deploying UI Data Provider --'); + const uiDataProvider = await deployWithVerify( + new UIDataProvider__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/misc/UIDataProvider.sol:UIDataProvider' + ); + + console.log('\n\t-- Deploying Profile Creation Proxy --'); + const profileCreationProxy = await deployWithVerify( + new ProfileCreationProxy__factory(deployer).deploy(profileCreatorAddress, lensHub.address, { + nonce: deployerNonce++, + }), + [deployer.address, lensHub.address], + 'contracts/misc/ProfileCreationProxy.sol:ProfileCreationProxy' + ); + + // Whitelist the collect modules + console.log('\n\t-- Whitelisting Collect Modules --'); + let governanceNonce = await ethers.provider.getTransactionCount(governance.address); + await waitForTx( + lensHub.whitelistCollectModule(feeCollectModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistCollectModule(limitedFeeCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(timedFeeCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(limitedTimedFeeCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(revertCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(freeCollectModule.address, true, { nonce: governanceNonce++ }) + ); + + // Whitelist the follow modules + console.log('\n\t-- Whitelisting Follow Modules --'); + await waitForTx( + lensHub.whitelistFollowModule(feeFollowModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistFollowModule(profileFollowModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistFollowModule(revertFollowModule.address, true, { nonce: governanceNonce++ }) + ); + // --- COMMENTED OUT AS THIS IS NOT A LAUNCH MODULE --- + // await waitForTx( + // lensHub.whitelistFollowModule(approvalFollowModule.address, true, { + // nonce: governanceNonce++, + // }) + // ); + + // Whitelist the reference module + console.log('\n\t-- Whitelisting Reference Module --'); + await waitForTx( + lensHub.whitelistReferenceModule(followerOnlyReferenceModule.address, true, { + nonce: governanceNonce++, + }) + ); + + // Whitelist the profile creation proxy + console.log('\n\t-- Whitelisting Profile Creation Proxy --'); + await waitForTx( + lensHub.whitelistProfileCreator(profileCreationProxy.address, true, { + nonce: governanceNonce++, + }) + ); + + // Save and log the addresses + const addrs = { + 'lensHub proxy': lensHub.address, + 'lensHub impl:': lensHubImpl.address, + 'publishing logic lib': publishingLogic.address, + 'interaction logic lib': interactionLogic.address, + 'profile token URI logic lib': profileTokenURILogic.address, + 'follow NFT impl': followNFTImplAddress, + 'collect NFT impl': collectNFTImplAddress, + 'lens periphery': lensPeriphery.address, + 'module globals': moduleGlobals.address, + 'fee collect module': feeCollectModule.address, + 'limited fee collect module': limitedFeeCollectModule.address, + 'timed fee collect module': timedFeeCollectModule.address, + 'limited timed fee collect module': limitedTimedFeeCollectModule.address, + 'revert collect module': revertCollectModule.address, + 'free collect module': freeCollectModule.address, + 'fee follow module': feeFollowModule.address, + 'profile follow module': profileFollowModule.address, + 'revert follow module': revertFollowModule.address, + // --- COMMENTED OUT AS THIS IS NOT A LAUNCH MODULE --- + // 'approval follow module': approvalFollowModule.address, + 'follower only reference module': followerOnlyReferenceModule.address, + 'UI data provider': uiDataProvider.address, + 'Profile creation proxy': profileCreationProxy.address, + }; + const json = JSON.stringify(addrs, null, 2); + console.log(json); + + fs.writeFileSync('addresses.json', json, 'utf-8'); + } +); diff --git a/lens-protocol/core/tasks/full-deploy.ts b/lens-protocol/core/tasks/full-deploy.ts new file mode 100644 index 0000000..352fcda --- /dev/null +++ b/lens-protocol/core/tasks/full-deploy.ts @@ -0,0 +1,340 @@ +import '@nomiclabs/hardhat-ethers'; +import { hexlify, keccak256, RLP } from 'ethers/lib/utils'; +import fs from 'fs'; +import { task } from 'hardhat/config'; +import { + LensHub__factory, + ApprovalFollowModule__factory, + CollectNFT__factory, + Currency__factory, + FreeCollectModule__factory, + FeeCollectModule__factory, + FeeFollowModule__factory, + FollowerOnlyReferenceModule__factory, + FollowNFT__factory, + InteractionLogic__factory, + LimitedFeeCollectModule__factory, + LimitedTimedFeeCollectModule__factory, + ModuleGlobals__factory, + PublishingLogic__factory, + RevertCollectModule__factory, + TimedFeeCollectModule__factory, + TransparentUpgradeableProxy__factory, + ProfileTokenURILogic__factory, + LensPeriphery__factory, + UIDataProvider__factory, + ProfileFollowModule__factory, + RevertFollowModule__factory, + ProfileCreationProxy__factory, + IERC20Burnable__factory, + IKlimaInfinity__factory, + CarbonRetireBase__factory, + PartialCarbonRetirementCollectModule__factory, +} from '../typechain-types'; +import { deployContract, waitForTx } from './helpers/utils'; + +const TREASURY_FEE_BPS = 50; +const LENS_HUB_NFT_NAME = 'Lens Protocol Profiles'; +const LENS_HUB_NFT_SYMBOL = 'LPP'; + +task('full-deploy', 'deploys the entire Lens Protocol').setAction(async ({}, hre) => { + // Note that the use of these signers is a placeholder and is not meant to be used in + // production. + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + const treasuryAddress = accounts[2].address; + const proxyAdminAddress = deployer.address; + const profileCreatorAddress = deployer.address; + + // Nonce management in case of deployment issues + let deployerNonce = await ethers.provider.getTransactionCount(deployer.address); + + console.log('\n\t-- Deploying Module Globals --'); + const moduleGlobals = await deployContract( + new ModuleGlobals__factory(deployer).deploy( + governance.address, + treasuryAddress, + TREASURY_FEE_BPS, + { nonce: deployerNonce++ } + ) + ); + + console.log('\n\t-- Deploying Logic Libs --'); + + const publishingLogic = await deployContract( + new PublishingLogic__factory(deployer).deploy({ nonce: deployerNonce++ }) + ); + const interactionLogic = await deployContract( + new InteractionLogic__factory(deployer).deploy({ nonce: deployerNonce++ }) + ); + const profileTokenURILogic = await deployContract( + new ProfileTokenURILogic__factory(deployer).deploy({ nonce: deployerNonce++ }) + ); + const hubLibs = { + 'contracts/libraries/PublishingLogic.sol:PublishingLogic': publishingLogic.address, + 'contracts/libraries/InteractionLogic.sol:InteractionLogic': interactionLogic.address, + 'contracts/libraries/ProfileTokenURILogic.sol:ProfileTokenURILogic': + profileTokenURILogic.address, + }; + + // Here, we pre-compute the nonces and addresses used to deploy the contracts. + // const nonce = await deployer.getTransactionCount(); + const followNFTNonce = hexlify(deployerNonce + 1); + const collectNFTNonce = hexlify(deployerNonce + 2); + const hubProxyNonce = hexlify(deployerNonce + 3); + + const followNFTImplAddress = + '0x' + keccak256(RLP.encode([deployer.address, followNFTNonce])).substr(26); + const collectNFTImplAddress = + '0x' + keccak256(RLP.encode([deployer.address, collectNFTNonce])).substr(26); + const hubProxyAddress = + '0x' + keccak256(RLP.encode([deployer.address, hubProxyNonce])).substr(26); + + // Next, we deploy first the hub implementation, then the followNFT implementation, the collectNFT, and finally the + // hub proxy with initialization. + console.log('\n\t-- Deploying Hub Implementation --'); + + const lensHubImpl = await deployContract( + new LensHub__factory(hubLibs, deployer).deploy(followNFTImplAddress, collectNFTImplAddress, { + nonce: deployerNonce++, + }) + ); + + console.log('\n\t-- Deploying Follow & Collect NFT Implementations --'); + await deployContract( + new FollowNFT__factory(deployer).deploy(hubProxyAddress, { nonce: deployerNonce++ }) + ); + await deployContract( + new CollectNFT__factory(deployer).deploy(hubProxyAddress, { nonce: deployerNonce++ }) + ); + + let data = lensHubImpl.interface.encodeFunctionData('initialize', [ + LENS_HUB_NFT_NAME, + LENS_HUB_NFT_SYMBOL, + governance.address, + ]); + + console.log('\n\t-- Deploying Hub Proxy --'); + let proxy = await deployContract( + new TransparentUpgradeableProxy__factory(deployer).deploy( + lensHubImpl.address, + proxyAdminAddress, + data, + { nonce: deployerNonce++ } + ) + ); + + // Connect the hub proxy to the LensHub factory and the governance for ease of use. + const lensHub = LensHub__factory.connect(proxy.address, governance); + + console.log('\n\t-- Deploying Lens Periphery --'); + const lensPeriphery = await new LensPeriphery__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }); + + // Currency + console.log('\n\t-- Deploying Currency --'); + const currency = await deployContract( + new Currency__factory(deployer).deploy({ nonce: deployerNonce++ }) + ); + + // Deploy collect modules + console.log('\n\t-- Deploying feeCollectModule --'); + const feeCollectModule = await deployContract( + new FeeCollectModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }) + ); + console.log('\n\t-- Deploying limitedFeeCollectModule --'); + const limitedFeeCollectModule = await deployContract( + new LimitedFeeCollectModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }) + ); + console.log('\n\t-- Deploying timedFeeCollectModule --'); + const timedFeeCollectModule = await deployContract( + new TimedFeeCollectModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }) + ); + console.log('\n\t-- Deploying limitedTimedFeeCollectModule --'); + const limitedTimedFeeCollectModule = await deployContract( + new LimitedTimedFeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address, + { nonce: deployerNonce++ } + ) + ); + + console.log('\n\t-- Deploying revertCollectModule --'); + const revertCollectModule = await deployContract( + new RevertCollectModule__factory(deployer).deploy({ nonce: deployerNonce++ }) + ); + console.log('\n\t-- Deploying freeCollectModule --'); + const freeCollectModule = await deployContract( + new FreeCollectModule__factory(deployer).deploy(lensHub.address, { nonce: deployerNonce++ }) + ); + + + console.log('\n\t-- Deploying partialCarbonRetirementCollectModule --'); + const partialCarbonRetirementCollectModule = await deployContract( + new PartialCarbonRetirementCollectModule__factory(deployer).deploy(lensHub.address, "0x8cE54d9625371fb2a068986d32C85De8E6e995f8", "0x8cE54d9625371fb2a068986d32C85De8E6e995f8", { nonce: deployerNonce++ }) + ); + + //IERC20Burnable__factory, + //IKlimaInfinity__factory, + //CarbonRetireBase__factory, + + // Deploy follow modules + console.log('\n\t-- Deploying feeFollowModule --'); + const feeFollowModule = await deployContract( + new FeeFollowModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }) + ); + console.log('\n\t-- Deploying profileFollowModule --'); + const profileFollowModule = await deployContract( + new ProfileFollowModule__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }) + ); + console.log('\n\t-- Deploying revertFollowModule --'); + const revertFollowModule = await deployContract( + new RevertFollowModule__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }) + ); + // --- COMMENTED OUT AS THIS IS NOT A LAUNCH MODULE --- + // console.log('\n\t-- Deploying approvalFollowModule --'); + // const approvalFollowModule = await deployContract( + // new ApprovalFollowModule__factory(deployer).deploy(lensHub.address, { nonce: deployerNonce++ }) + // ); + + // Deploy reference module + console.log('\n\t-- Deploying followerOnlyReferenceModule --'); + const followerOnlyReferenceModule = await deployContract( + new FollowerOnlyReferenceModule__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }) + ); + + // Deploy UIDataProvider + console.log('\n\t-- Deploying UI Data Provider --'); + const uiDataProvider = await deployContract( + new UIDataProvider__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }) + ); + + console.log('\n\t-- Deploying Profile Creation Proxy --'); + const profileCreationProxy = await deployContract( + new ProfileCreationProxy__factory(deployer).deploy(profileCreatorAddress, lensHub.address, { + nonce: deployerNonce++, + }) + ); + + // Whitelist the collect modules + console.log('\n\t-- Whitelisting Collect Modules --'); + let governanceNonce = await ethers.provider.getTransactionCount(governance.address); + await waitForTx( + lensHub.whitelistCollectModule(feeCollectModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistCollectModule(limitedFeeCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(timedFeeCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(limitedTimedFeeCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(revertCollectModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistCollectModule(freeCollectModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistCollectModule(partialCarbonRetirementCollectModule.address, true, { nonce: governanceNonce++ }) + ); + + // Whitelist the follow modules + console.log('\n\t-- Whitelisting Follow Modules --'); + await waitForTx( + lensHub.whitelistFollowModule(feeFollowModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistFollowModule(profileFollowModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistFollowModule(revertFollowModule.address, true, { nonce: governanceNonce++ }) + ); + // --- COMMENTED OUT AS THIS IS NOT A LAUNCH MODULE --- + // await waitForTx( + // lensHub.whitelistFollowModule(approvalFollowModule.address, true, { nonce: governanceNonce++ }) + // ); + + // Whitelist the reference module + console.log('\n\t-- Whitelisting Reference Module --'); + await waitForTx( + lensHub.whitelistReferenceModule(followerOnlyReferenceModule.address, true, { + nonce: governanceNonce++, + }) + ); + + // Whitelist the currency + console.log('\n\t-- Whitelisting Currency in Module Globals --'); + await waitForTx( + moduleGlobals + .connect(governance) + .whitelistCurrency(currency.address, true, { nonce: governanceNonce++ }) + ); + + // Whitelist the profile creation proxy + console.log('\n\t-- Whitelisting Profile Creation Proxy --'); + await waitForTx( + lensHub.whitelistProfileCreator(profileCreationProxy.address, true, { + nonce: governanceNonce++, + }) + ); + + // Save and log the addresses + const addrs = { + 'lensHub proxy': lensHub.address, + 'lensHub impl:': lensHubImpl.address, + 'publishing logic lib': publishingLogic.address, + 'interaction logic lib': interactionLogic.address, + 'follow NFT impl': followNFTImplAddress, + 'collect NFT impl': collectNFTImplAddress, + currency: currency.address, + 'lens periphery': lensPeriphery.address, + 'module globals': moduleGlobals.address, + 'fee collect module': feeCollectModule.address, + 'limited fee collect module': limitedFeeCollectModule.address, + 'timed fee collect module': timedFeeCollectModule.address, + 'limited timed fee collect module': limitedTimedFeeCollectModule.address, + 'revert collect module': revertCollectModule.address, + 'free collect module': freeCollectModule.address, + 'partial carbon retirement collect module': partialCarbonRetirementCollectModule.address, + 'fee follow module': feeFollowModule.address, + 'profile follow module': profileFollowModule.address, + 'revert follow module': revertFollowModule.address, + // --- COMMENTED OUT AS THIS IS NOT A LAUNCH MODULE --- + // 'approval follow module': approvalFollowModule.address, + 'follower only reference module': followerOnlyReferenceModule.address, + 'UI data provider': uiDataProvider.address, + 'Profile creation proxy': profileCreationProxy.address, + }; + const json = JSON.stringify(addrs, null, 2); + console.log(json); + + fs.writeFileSync('addresses.json', json, 'utf-8'); +}); diff --git a/lens-protocol/core/tasks/helpers/utils.ts b/lens-protocol/core/tasks/helpers/utils.ts new file mode 100644 index 0000000..e423fef --- /dev/null +++ b/lens-protocol/core/tasks/helpers/utils.ts @@ -0,0 +1,83 @@ +import '@nomiclabs/hardhat-ethers'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { Contract, ContractTransaction } from 'ethers'; +import fs from 'fs'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; + +export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + +export enum ProtocolState { + Unpaused, + PublishingPaused, + Paused, +} + +export function getAddrs(): any { + const json = fs.readFileSync('addresses.json', 'utf8'); + const addrs = JSON.parse(json); + return addrs; +} + +export async function waitForTx(tx: Promise) { + await (await tx).wait(); +} + +export async function deployContract(tx: any): Promise { + const result = await tx; + await result.deployTransaction.wait(); + return result; +} + +export async function deployWithVerify( + tx: any, + args: any, + contractPath: string +): Promise { + const deployedContract = await deployContract(tx); + let count = 0; + let maxTries = 8; + const runtimeHRE = require('hardhat'); + while (true) { + await delay(10000); + try { + console.log('Verifying contract at', deployedContract.address); + await runtimeHRE.run('verify:verify', { + address: deployedContract.address, + constructorArguments: args, + contract: contractPath, + }); + break; + } catch (error) { + if (String(error).includes('Already Verified')) { + console.log( + `Already verified contract at ${contractPath} at address ${deployedContract.address}` + ); + break; + } + if (++count == maxTries) { + console.log( + `Failed to verify contract at ${contractPath} at address ${deployedContract.address}, error: ${error}` + ); + break; + } + console.log(`Retrying... Retry #${count}, last error: ${error}`); + } + } + + return deployedContract; +} + +export async function initEnv(hre: HardhatRuntimeEnvironment): Promise { + const ethers = hre.ethers; // This allows us to access the hre (Hardhat runtime environment)'s injected ethers instance easily + + const accounts = await ethers.getSigners(); // This returns an array of the default signers connected to the hre's ethers instance + const governance = accounts[1]; + const treasury = accounts[2]; + const user = accounts[3]; + + return [governance, treasury, user]; +} + +async function delay(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/lens-protocol/core/tasks/testnet-full-deploy-verify.ts b/lens-protocol/core/tasks/testnet-full-deploy-verify.ts new file mode 100644 index 0000000..32f66af --- /dev/null +++ b/lens-protocol/core/tasks/testnet-full-deploy-verify.ts @@ -0,0 +1,368 @@ +import '@nomiclabs/hardhat-ethers'; +import { hexlify, keccak256, RLP } from 'ethers/lib/utils'; +import fs from 'fs'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { + LensHub__factory, + ApprovalFollowModule__factory, + CollectNFT__factory, + FreeCollectModule__factory, + FeeCollectModule__factory, + FeeFollowModule__factory, + FollowerOnlyReferenceModule__factory, + FollowNFT__factory, + InteractionLogic__factory, + LimitedFeeCollectModule__factory, + LimitedTimedFeeCollectModule__factory, + ModuleGlobals__factory, + PublishingLogic__factory, + RevertCollectModule__factory, + TimedFeeCollectModule__factory, + TransparentUpgradeableProxy__factory, + ProfileTokenURILogic__factory, + LensPeriphery__factory, + MockProfileCreationProxy__factory, + UIDataProvider__factory, + ProfileFollowModule__factory, + RevertFollowModule__factory, +} from '../typechain-types'; +import { deployWithVerify, waitForTx } from './helpers/utils'; + +const TREASURY_FEE_BPS = 50; +const LENS_HUB_NFT_NAME = 'Lens Protocol Profiles'; +const LENS_HUB_NFT_SYMBOL = 'LPP'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +/** + * @dev Note that this script uses the default ethers signers. + * Care should be taken to also ensure that the following addresses end up properly set: + * 1. LensHub Proxy Admin + * 2. LensHub Governance + * 3. ModuleGlobals Governance + * 3. ModuleGlobals Treasury + * + * Furthermore, This script is a variation of the standard full-deploy-verify script, it still does not whitelist profile + * creators or deploy/whitelist a currency, but it *does* deploy a profile creation proxy. + */ +task( + 'testnet-full-deploy-verify', + 'deploys the entire Lens Protocol with explorer verification (testnet)' +).setAction(async ({}, hre) => { + // Note that the use of these signers is a placeholder and is not meant to be used in + // production. + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + const treasuryAddress = accounts[2].address; + + // Nonce management in case of deployment issues + let deployerNonce = await ethers.provider.getTransactionCount(deployer.address); + + console.log('\n\t-- Deploying Module Globals --'); + const moduleGlobals = await deployWithVerify( + new ModuleGlobals__factory(deployer).deploy( + governance.address, + treasuryAddress, + TREASURY_FEE_BPS, + { nonce: deployerNonce++ } + ), + [governance.address, treasuryAddress, TREASURY_FEE_BPS], + 'contracts/core/modules/ModuleGlobals.sol:ModuleGlobals' + ); + + console.log('\n\t-- Deploying Logic Libs --'); + + const publishingLogic = await deployWithVerify( + new PublishingLogic__factory(deployer).deploy({ nonce: deployerNonce++ }), + [], + 'contracts/libraries/PublishingLogic.sol:PublishingLogic' + ); + const interactionLogic = await deployWithVerify( + new InteractionLogic__factory(deployer).deploy({ nonce: deployerNonce++ }), + [], + 'contracts/libraries/InteractionLogic.sol:InteractionLogic' + ); + const profileTokenURILogic = await deployWithVerify( + new ProfileTokenURILogic__factory(deployer).deploy({ nonce: deployerNonce++ }), + [], + 'contracts/libraries/ProfileTokenURILogic.sol:ProfileTokenURILogic' + ); + const hubLibs = { + 'contracts/libraries/PublishingLogic.sol:PublishingLogic': publishingLogic.address, + 'contracts/libraries/InteractionLogic.sol:InteractionLogic': interactionLogic.address, + 'contracts/libraries/ProfileTokenURILogic.sol:ProfileTokenURILogic': + profileTokenURILogic.address, + }; + + // Here, we pre-compute the nonces and addresses used to deploy the contracts. + // const nonce = await deployer.getTransactionCount(); + const followNFTNonce = hexlify(deployerNonce + 1); + const collectNFTNonce = hexlify(deployerNonce + 2); + const hubProxyNonce = hexlify(deployerNonce + 3); + + const followNFTImplAddress = + '0x' + keccak256(RLP.encode([deployer.address, followNFTNonce])).substr(26); + const collectNFTImplAddress = + '0x' + keccak256(RLP.encode([deployer.address, collectNFTNonce])).substr(26); + const hubProxyAddress = + '0x' + keccak256(RLP.encode([deployer.address, hubProxyNonce])).substr(26); + + // Next, we deploy first the hub implementation, then the followNFT implementation, the collectNFT, and finally the + // hub proxy with initialization. + console.log('\n\t-- Deploying Hub Implementation --'); + + const lensHubImpl = await deployWithVerify( + new LensHub__factory(hubLibs, deployer).deploy(followNFTImplAddress, collectNFTImplAddress, { + nonce: deployerNonce++, + }), + [followNFTImplAddress, collectNFTImplAddress], + 'contracts/core/LensHub.sol:LensHub' + ); + + console.log('\n\t-- Deploying Follow & Collect NFT Implementations --'); + await deployWithVerify( + new FollowNFT__factory(deployer).deploy(hubProxyAddress, { nonce: deployerNonce++ }), + [hubProxyAddress], + 'contracts/core/FollowNFT.sol:FollowNFT' + ); + await deployWithVerify( + new CollectNFT__factory(deployer).deploy(hubProxyAddress, { nonce: deployerNonce++ }), + [hubProxyAddress], + 'contracts/core/CollectNFT.sol:CollectNFT' + ); + + let data = lensHubImpl.interface.encodeFunctionData('initialize', [ + LENS_HUB_NFT_NAME, + LENS_HUB_NFT_SYMBOL, + governance.address, + ]); + + console.log('\n\t-- Deploying Hub Proxy --'); + + let proxy = await deployWithVerify( + new TransparentUpgradeableProxy__factory(deployer).deploy( + lensHubImpl.address, + deployer.address, + data, + { nonce: deployerNonce++ } + ), + [lensHubImpl.address, deployer.address, data], + 'contracts/upgradeability/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy' + ); + + // Connect the hub proxy to the LensHub factory and the governance for ease of use. + const lensHub = LensHub__factory.connect(proxy.address, governance); + + const lensPeriphery = await deployWithVerify( + new LensPeriphery__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/misc/LensPeriphery.sol:LensPeriphery' + ); + + // Deploy collect modules + console.log('\n\t-- Deploying feeCollectModule --'); + const feeCollectModule = await deployWithVerify( + new FeeCollectModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/collect/FeeCollectModule.sol:FeeCollectModule' + ); + console.log('\n\t-- Deploying limitedFeeCollectModule --'); + const limitedFeeCollectModule = await deployWithVerify( + new LimitedFeeCollectModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/collect/LimitedFeeCollectModule.sol:LimitedFeeCollectModule' + ); + console.log('\n\t-- Deploying timedFeeCollectModule --'); + const timedFeeCollectModule = await deployWithVerify( + new TimedFeeCollectModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/collect/TimedFeeCollectModule.sol:TimedFeeCollectModule' + ); + console.log('\n\t-- Deploying limitedTimedFeeCollectModule --'); + const limitedTimedFeeCollectModule = await deployWithVerify( + new LimitedTimedFeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address, + { nonce: deployerNonce++ } + ), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/collect/LimitedTimedFeeCollectModule.sol:LimitedTimedFeeCollectModule' + ); + + console.log('\n\t-- Deploying revertCollectModule --'); + const revertCollectModule = await deployWithVerify( + new RevertCollectModule__factory(deployer).deploy({ nonce: deployerNonce++ }), + [], + 'contracts/core/modules/collect/RevertCollectModule.sol:RevertCollectModule' + ); + console.log('\n\t-- Deploying freeCollectModule --'); + const freeCollectModule = await deployWithVerify( + new FreeCollectModule__factory(deployer).deploy(lensHub.address, { nonce: deployerNonce++ }), + [lensHub.address], + 'contracts/core/modules/collect/FreeCollectModule.sol:FreeCollectModule' + ); + + // Deploy follow modules + console.log('\n\t-- Deploying feeFollowModule --'); + const feeFollowModule = await deployWithVerify( + new FeeFollowModule__factory(deployer).deploy(lensHub.address, moduleGlobals.address, { + nonce: deployerNonce++, + }), + [lensHub.address, moduleGlobals.address], + 'contracts/core/modules/follow/FeeFollowModule.sol:FeeFollowModule' + ); + console.log('\n\t-- Deploying profileFollowModule --'); + const profileFollowModule = await deployWithVerify( + new ProfileFollowModule__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/core/modules/follow/ProfileFollowModule.sol:ProfileFollowModule' + ); + console.log('\n\t-- Deploying revertFollowModule --'); + const revertFollowModule = await deployWithVerify( + new RevertFollowModule__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/core/modules/follow/RevertFollowModule.sol:RevertFollowModule' + ); + // --- COMMENTED OUT AS THIS IS NOT A LAUNCH MODULE --- + // console.log('\n\t-- Deploying approvalFollowModule --'); + // const approvalFollowModule = await deployWithVerify( + // new ApprovalFollowModule__factory(deployer).deploy(lensHub.address, { + // nonce: deployerNonce++, + // }), + // [lensHub.address], + // 'contracts/core/modules/follow/ApprovalFollowModule.sol:ApprovalFollowModule' + // ); + + // Deploy reference module + console.log('\n\t-- Deploying followerOnlyReferenceModule --'); + const followerOnlyReferenceModule = await deployWithVerify( + new FollowerOnlyReferenceModule__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/core/modules/reference/FollowerOnlyReferenceModule.sol:FollowerOnlyReferenceModule' + ); + + // Deploy UIDataProvider + console.log('\n\t-- Deploying UI Data Provider --'); + const uiDataProvider = await deployWithVerify( + new UIDataProvider__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/misc/UIDataProvider.sol:UIDataProvider' + ); + + // Deploy MockProfileCreationProxy + console.log('\n\t-- Deploying Profile Creation Proxy --'); + const profileCreationProxy = await deployWithVerify( + new MockProfileCreationProxy__factory(deployer).deploy(lensHub.address, { + nonce: deployerNonce++, + }), + [lensHub.address], + 'contracts/mocks/MockProfileCreationProxy.sol:MockProfileCreationProxy' + ); + + // Whitelist the collect modules + console.log('\n\t-- Whitelisting Collect Modules --'); + let governanceNonce = await ethers.provider.getTransactionCount(governance.address); + await waitForTx( + lensHub.whitelistCollectModule(feeCollectModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistCollectModule(limitedFeeCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(timedFeeCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(limitedTimedFeeCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(revertCollectModule.address, true, { + nonce: governanceNonce++, + }) + ); + await waitForTx( + lensHub.whitelistCollectModule(freeCollectModule.address, true, { nonce: governanceNonce++ }) + ); + + // Whitelist the follow modules + console.log('\n\t-- Whitelisting Follow Modules --'); + await waitForTx( + lensHub.whitelistFollowModule(feeFollowModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistFollowModule(profileFollowModule.address, true, { nonce: governanceNonce++ }) + ); + await waitForTx( + lensHub.whitelistFollowModule(revertFollowModule.address, true, { nonce: governanceNonce++ }) + ); + // --- COMMENTED OUT AS THIS IS NOT A LAUNCH MODULE --- + // await waitForTx( + // lensHub.whitelistFollowModule(approvalFollowModule.address, true, { + // nonce: governanceNonce++, + // }) + // ); + + // Whitelist the reference module + console.log('\n\t-- Whitelisting Reference Module --'); + await waitForTx( + lensHub.whitelistReferenceModule(followerOnlyReferenceModule.address, true, { + nonce: governanceNonce++, + }) + ); + + // Save and log the addresses + const addrs = { + 'lensHub proxy': lensHub.address, + 'lensHub impl:': lensHubImpl.address, + 'publishing logic lib': publishingLogic.address, + 'interaction logic lib': interactionLogic.address, + 'profile token URI logic lib': profileTokenURILogic.address, + 'follow NFT impl': followNFTImplAddress, + 'collect NFT impl': collectNFTImplAddress, + 'lens periphery': lensPeriphery.address, + 'module globals': moduleGlobals.address, + 'fee collect module': feeCollectModule.address, + 'limited fee collect module': limitedFeeCollectModule.address, + 'timed fee collect module': timedFeeCollectModule.address, + 'limited timed fee collect module': limitedTimedFeeCollectModule.address, + 'revert collect module': revertCollectModule.address, + 'free collect module': freeCollectModule.address, + 'fee follow module': feeFollowModule.address, + 'profile follow module': profileFollowModule.address, + 'revert follow module': revertFollowModule.address, + // --- COMMENTED OUT AS THIS IS NOT A LAUNCH MODULE --- + // 'approval follow module': approvalFollowModule.address, + 'follower only reference module': followerOnlyReferenceModule.address, + 'profile creation proxy': profileCreationProxy.address, + 'UI data provider': uiDataProvider.address, + }; + const json = JSON.stringify(addrs, null, 2); + console.log(json); + + fs.writeFileSync('addresses.json', json, 'utf-8'); +}); diff --git a/lens-protocol/core/tasks/whitelist-currency.ts b/lens-protocol/core/tasks/whitelist-currency.ts new file mode 100644 index 0000000..57f3ffd --- /dev/null +++ b/lens-protocol/core/tasks/whitelist-currency.ts @@ -0,0 +1,18 @@ +import '@nomiclabs/hardhat-ethers'; +import { task } from 'hardhat/config'; +import { ModuleGlobals__factory } from '../typechain-types'; +import { waitForTx } from './helpers/utils'; + +task('whitelist-currency', 'whitelists a currency in the module globals') + .addParam('gov') + .addParam('globals') + .addParam('currency') + .addParam('whitelist') + .setAction(async ({ gov, globals, currency, whitelist }, hre) => { + const ethers = hre.ethers; + const governance = await ethers.getSigner(gov); + + const moduleGlobals = ModuleGlobals__factory.connect(globals, governance); + + await waitForTx(moduleGlobals.connect(governance).whitelistCurrency(currency, whitelist)); + }); diff --git a/lens-protocol/core/test/__setup.spec.ts b/lens-protocol/core/test/__setup.spec.ts new file mode 100644 index 0000000..31e6019 --- /dev/null +++ b/lens-protocol/core/test/__setup.spec.ts @@ -0,0 +1,271 @@ +import { AbiCoder } from '@ethersproject/contracts/node_modules/@ethersproject/abi'; +import { parseEther } from '@ethersproject/units'; +import '@nomiclabs/hardhat-ethers'; +import { expect, use } from 'chai'; +import { solidity } from 'ethereum-waffle'; +import { BytesLike, Signer, Wallet } from 'ethers'; +import { ethers } from 'hardhat'; +import { + ApprovalFollowModule, + ApprovalFollowModule__factory, + CollectNFT__factory, + Currency, + Currency__factory, + FreeCollectModule, + FreeCollectModule__factory, + Events, + Events__factory, + FeeCollectModule, + FeeCollectModule__factory, + FeeFollowModule, + FeeFollowModule__factory, + FollowerOnlyReferenceModule, + FollowerOnlyReferenceModule__factory, + FollowNFT__factory, + Helper, + Helper__factory, + InteractionLogic__factory, + LensHub, + LensHub__factory, + LimitedFeeCollectModule, + LimitedFeeCollectModule__factory, + LimitedTimedFeeCollectModule, + LimitedTimedFeeCollectModule__factory, + MockFollowModule, + MockFollowModule__factory, + MockReferenceModule, + MockReferenceModule__factory, + ModuleGlobals, + ModuleGlobals__factory, + ProfileTokenURILogic__factory, + PublishingLogic__factory, + RevertCollectModule, + RevertCollectModule__factory, + TimedFeeCollectModule, + TimedFeeCollectModule__factory, + TransparentUpgradeableProxy__factory, + LensPeriphery, + LensPeriphery__factory, + ProfileFollowModule, + ProfileFollowModule__factory, + FollowNFT, + CollectNFT, + RevertFollowModule, + RevertFollowModule__factory, +} from '../typechain-types'; +import { LensHubLibraryAddresses } from '../typechain-types/factories/LensHub__factory'; +import { FAKE_PRIVATEKEY, ZERO_ADDRESS } from './helpers/constants'; +import { + computeContractAddress, + ProtocolState, + revertToSnapshot, + takeSnapshot, +} from './helpers/utils'; + +use(solidity); + +export const CURRENCY_MINT_AMOUNT = parseEther('100'); +export const BPS_MAX = 10000; +export const TREASURY_FEE_BPS = 50; +export const REFERRAL_FEE_BPS = 250; +export const MAX_PROFILE_IMAGE_URI_LENGTH = 6000; +export const LENS_HUB_NFT_NAME = 'Lens Protocol Profiles'; +export const LENS_HUB_NFT_SYMBOL = 'LPP'; +export const MOCK_PROFILE_HANDLE = 'plant1ghost.eth'; +export const LENS_PERIPHERY_NAME = 'LensPeriphery'; +export const FIRST_PROFILE_ID = 1; +export const MOCK_URI = 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR'; +export const OTHER_MOCK_URI = 'https://ipfs.io/ipfs/QmSfyMcnh1wnJHrAWCBjZHapTS859oNSsuDFiAPPdAHgHP'; +export const MOCK_PROFILE_URI = + 'https://ipfs.io/ipfs/Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu'; +export const MOCK_FOLLOW_NFT_URI = + 'https://ipfs.fleek.co/ipfs/ghostplantghostplantghostplantghostplantghostplantghostplan'; + +export let accounts: Signer[]; +export let deployer: Signer; +export let user: Signer; +export let userTwo: Signer; +export let userThree: Signer; +export let governance: Signer; +export let deployerAddress: string; +export let userAddress: string; +export let userTwoAddress: string; +export let userThreeAddress: string; +export let governanceAddress: string; +export let treasuryAddress: string; +export let testWallet: Wallet; +export let lensHubImpl: LensHub; +export let lensHub: LensHub; +export let currency: Currency; +export let abiCoder: AbiCoder; +export let mockModuleData: BytesLike; +export let hubLibs: LensHubLibraryAddresses; +export let eventsLib: Events; +export let moduleGlobals: ModuleGlobals; +export let helper: Helper; +export let lensPeriphery: LensPeriphery; +export let followNFTImpl: FollowNFT; +export let collectNFTImpl: CollectNFT; + +/* Modules */ + +// Collect +export let feeCollectModule: FeeCollectModule; +export let timedFeeCollectModule: TimedFeeCollectModule; +export let freeCollectModule: FreeCollectModule; +export let revertCollectModule: RevertCollectModule; +export let limitedFeeCollectModule: LimitedFeeCollectModule; +export let limitedTimedFeeCollectModule: LimitedTimedFeeCollectModule; + +// Follow +export let approvalFollowModule: ApprovalFollowModule; +export let profileFollowModule: ProfileFollowModule; +export let feeFollowModule: FeeFollowModule; +export let revertFollowModule: RevertFollowModule; +export let mockFollowModule: MockFollowModule; + +// Reference +export let followerOnlyReferenceModule: FollowerOnlyReferenceModule; +export let mockReferenceModule: MockReferenceModule; + +export function makeSuiteCleanRoom(name: string, tests: () => void) { + describe(name, () => { + beforeEach(async function () { + await takeSnapshot(); + }); + tests(); + afterEach(async function () { + await revertToSnapshot(); + }); + }); +} + +before(async function () { + abiCoder = ethers.utils.defaultAbiCoder; + testWallet = new ethers.Wallet(FAKE_PRIVATEKEY).connect(ethers.provider); + accounts = await ethers.getSigners(); + deployer = accounts[0]; + user = accounts[1]; + userTwo = accounts[2]; + userThree = accounts[4]; + governance = accounts[3]; + + deployerAddress = await deployer.getAddress(); + userAddress = await user.getAddress(); + userTwoAddress = await userTwo.getAddress(); + userThreeAddress = await userThree.getAddress(); + governanceAddress = await governance.getAddress(); + treasuryAddress = await accounts[4].getAddress(); + mockModuleData = abiCoder.encode(['uint256'], [1]); + // Deployment + helper = await new Helper__factory(deployer).deploy(); + moduleGlobals = await new ModuleGlobals__factory(deployer).deploy( + governanceAddress, + treasuryAddress, + TREASURY_FEE_BPS + ); + const publishingLogic = await new PublishingLogic__factory(deployer).deploy(); + const interactionLogic = await new InteractionLogic__factory(deployer).deploy(); + const profileTokenURILogic = await new ProfileTokenURILogic__factory(deployer).deploy(); + hubLibs = { + 'contracts/libraries/PublishingLogic.sol:PublishingLogic': publishingLogic.address, + 'contracts/libraries/InteractionLogic.sol:InteractionLogic': interactionLogic.address, + 'contracts/libraries/ProfileTokenURILogic.sol:ProfileTokenURILogic': + profileTokenURILogic.address, + }; + + // Here, we pre-compute the nonces and addresses used to deploy the contracts. + const nonce = await deployer.getTransactionCount(); + // nonce + 0 is follow NFT impl + // nonce + 1 is collect NFT impl + // nonce + 2 is impl + // nonce + 3 is hub proxy + + const hubProxyAddress = computeContractAddress(deployerAddress, nonce + 3); //'0x' + keccak256(RLP.encode([deployerAddress, hubProxyNonce])).substr(26); + + followNFTImpl = await new FollowNFT__factory(deployer).deploy(hubProxyAddress); + collectNFTImpl = await new CollectNFT__factory(deployer).deploy(hubProxyAddress); + + lensHubImpl = await new LensHub__factory(hubLibs, deployer).deploy( + followNFTImpl.address, + collectNFTImpl.address + ); + + let data = lensHubImpl.interface.encodeFunctionData('initialize', [ + LENS_HUB_NFT_NAME, + LENS_HUB_NFT_SYMBOL, + governanceAddress, + ]); + let proxy = await new TransparentUpgradeableProxy__factory(deployer).deploy( + lensHubImpl.address, + deployerAddress, + data + ); + + // Connect the hub proxy to the LensHub factory and the user for ease of use. + lensHub = LensHub__factory.connect(proxy.address, user); + + // LensPeriphery + lensPeriphery = await new LensPeriphery__factory(deployer).deploy(lensHub.address); + lensPeriphery = lensPeriphery.connect(user); + + // Currency + currency = await new Currency__factory(deployer).deploy(); + + // Modules + freeCollectModule = await new FreeCollectModule__factory(deployer).deploy(lensHub.address); + revertCollectModule = await new RevertCollectModule__factory(deployer).deploy(); + feeCollectModule = await new FeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ); + timedFeeCollectModule = await new TimedFeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ); + limitedFeeCollectModule = await new LimitedFeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ); + limitedTimedFeeCollectModule = await new LimitedTimedFeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ); + + feeFollowModule = await new FeeFollowModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ); + profileFollowModule = await new ProfileFollowModule__factory(deployer).deploy(lensHub.address); + approvalFollowModule = await new ApprovalFollowModule__factory(deployer).deploy(lensHub.address); + revertFollowModule = await new RevertFollowModule__factory(deployer).deploy(lensHub.address); + followerOnlyReferenceModule = await new FollowerOnlyReferenceModule__factory(deployer).deploy( + lensHub.address + ); + + mockFollowModule = await new MockFollowModule__factory(deployer).deploy(); + mockReferenceModule = await new MockReferenceModule__factory(deployer).deploy(); + + await expect(lensHub.connect(governance).setState(ProtocolState.Unpaused)).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistProfileCreator(userAddress, true) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistProfileCreator(userTwoAddress, true) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistProfileCreator(userThreeAddress, true) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistProfileCreator(testWallet.address, true) + ).to.not.be.reverted; + + expect(lensHub).to.not.be.undefined; + expect(currency).to.not.be.undefined; + expect(timedFeeCollectModule).to.not.be.undefined; + expect(mockFollowModule).to.not.be.undefined; + expect(mockReferenceModule).to.not.be.undefined; + + // Event library deployment is only needed for testing and is not reproduced in the live environment + eventsLib = await new Events__factory(deployer).deploy(); +}); diff --git a/lens-protocol/core/test/emptyrun.coverage.ts b/lens-protocol/core/test/emptyrun.coverage.ts new file mode 100644 index 0000000..ebbd4de --- /dev/null +++ b/lens-protocol/core/test/emptyrun.coverage.ts @@ -0,0 +1,3 @@ +import { makeSuiteCleanRoom } from './__setup.spec'; + +makeSuiteCleanRoom('Empty Run for Coverage', function () {}); diff --git a/lens-protocol/core/test/helpers/constants.ts b/lens-protocol/core/test/helpers/constants.ts new file mode 100644 index 0000000..75a0c59 --- /dev/null +++ b/lens-protocol/core/test/helpers/constants.ts @@ -0,0 +1,8 @@ +export const MAX_UINT256 = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'; +export const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + +// Fetched from $npx hardhat node, account # 7 +export const FAKE_PRIVATEKEY = '0xa2e0097c961c67ec197b6865d7ecea6caffc68ebeb00e6050368c8f67fc9c588'; + +export const HARDHAT_CHAINID = 31337; diff --git a/lens-protocol/core/test/helpers/errors.ts b/lens-protocol/core/test/helpers/errors.ts new file mode 100644 index 0000000..ecb3185 --- /dev/null +++ b/lens-protocol/core/test/helpers/errors.ts @@ -0,0 +1,51 @@ +export const ERRORS = { + CANNOT_INIT_IMPL: 'CannotInitImplementation()', + INITIALIZED: 'Initialized()', + SIGNATURE_EXPIRED: 'SignatureExpired()', + ZERO_SPENDER: 'ZeroSpender()', + SIGNATURE_INVALID: 'SignatureInvalid()', + NOT_OWNER_OR_APPROVED: 'NotOwnerOrApproved()', + NOT_HUB: 'NotHub()', + TOKEN_DOES_NOT_EXIST: 'TokenDoesNotExist()', + CALLER_NOT_WHITELSITED_MODULE: 'CallerNotWhitelistedModule()', + NOT_GOVERNANCE: 'NotGovernance()', + NOT_GOVERNANCE_OR_EMERGENCY_ADMIN: 'NotGovernanceOrEmergencyAdmin()', + EMERGENCY_ADMIN_CANNOT_UNPAUSE: 'EmergencyAdminCannotUnpause()', + COLLECT_MODULE_NOT_WHITELISTED: 'CollectModuleNotWhitelisted()', + FOLLOW_MODULE_NOT_WHITELISTED: 'FollowModuleNotWhitelisted()', + REFERENCE_MODULE_NOT_WHITELISTED: 'ReferenceModuleNotWhitelisted()', + PROFILE_CREATOR_NOT_WHITELISTED: 'ProfileCreatorNotWhitelisted()', + NOT_PROFILE_OWNER: 'NotProfileOwner()', + NOT_PROFILE_OWNER_OR_DISPATCHER: 'NotProfileOwnerOrDispatcher()', + PUBLICATION_DOES_NOT_EXIST: 'PublicationDoesNotExist()', + PROFILE_HANDLE_TAKEN: 'HandleTaken()', + INVALID_HANDLE_LENGTH: 'HandleLengthInvalid()', + INVALID_IMAGE_URI_LENGTH: 'ProfileImageURILengthInvalid()', + HANDLE_CONTAINS_INVALID_CHARACTERS: 'HandleContainsInvalidCharacters()', + HANDLE_FIRST_CHARACTER_INVALID: 'HandleFirstCharInvalid()', + NOT_FOLLOW_NFT: 'CallerNotFollowNFT()', + NOT_COLLECT_NFT: 'CallerNotCollectNFT()', + BLOCK_NUMBER_INVALID: 'BlockNumberInvalid()', + INIT_PARAMS_INVALID: 'InitParamsInvalid()', + COLLECT_EXPIRED: 'CollectExpired()', + COLLECT_NOT_ALLOWED: 'CollectNotAllowed()', + MINT_LIMIT_EXCEEDED: 'MintLimitExceeded()', + FOLLOW_INVALID: 'FollowInvalid()', + MODULE_DATA_MISMATCH: 'ModuleDataMismatch()', + FOLLOW_NOT_APPROVED: 'FollowNotApproved()', + ARRAY_MISMATCH: 'ArrayMismatch()', + CANNOT_COMMENT_ON_SELF: 'CannotCommentOnSelf', + NOT_DISPATCHER: 'NotDispatcher()', + ERC721_NOT_OWN: 'ERC721: transfer of token that is not own', + ERC721_TRANSFER_NOT_OWNER_OR_APPROVED: 'ERC721: transfer caller is not owner nor approved', + ERC721_QUERY_FOR_NONEXISTENT_TOKEN: 'ERC721: owner query for nonexistent token', + ERC20_TRANSFER_EXCEEDS_ALLOWANCE: 'ERC20: transfer amount exceeds allowance', + ERC20_INSUFFICIENT_ALLOWANCE: 'ERC20: insufficient allowance', + NO_SELECTOR: + "Transaction reverted: function selector was not recognized and there's no fallback function", + PAUSED: 'Paused()', + PUBLISHING_PAUSED: 'PublishingPaused()', + NO_REASON_ABI_DECODE: + "Transaction reverted and Hardhat couldn't infer the reason. Please report this to help us improve Hardhat.", + INVALID_PARAMETER: 'InvalidParameter()', +}; diff --git a/lens-protocol/core/test/helpers/utils.ts b/lens-protocol/core/test/helpers/utils.ts new file mode 100644 index 0000000..ca58eda --- /dev/null +++ b/lens-protocol/core/test/helpers/utils.ts @@ -0,0 +1,1161 @@ +import '@nomiclabs/hardhat-ethers'; +import { BigNumberish, Bytes, logger, utils, BigNumber, Contract, Signer } from 'ethers'; +import { + eventsLib, + helper, + lensHub, + LENS_HUB_NFT_NAME, + lensPeriphery, + LENS_PERIPHERY_NAME, + testWallet, + user, +} from '../__setup.spec'; +import { expect } from 'chai'; +import { HARDHAT_CHAINID, MAX_UINT256 } from './constants'; +import { BytesLike, hexlify, keccak256, RLP, toUtf8Bytes } from 'ethers/lib/utils'; +import { LensHub__factory } from '../../typechain-types'; +import { TransactionReceipt, TransactionResponse } from '@ethersproject/providers'; +import hre, { ethers } from 'hardhat'; +import { readFileSync } from 'fs'; +import { join } from 'path'; +import { + CollectWithSigDataStruct, + CommentDataStruct, + CommentWithSigDataStruct, + CreateProfileDataStruct, + FollowWithSigDataStruct, + MirrorDataStruct, + MirrorWithSigDataStruct, + PostDataStruct, + PostWithSigDataStruct, +} from '../../typechain-types/LensHub'; + +export enum ProtocolState { + Unpaused, + PublishingPaused, + Paused, +} + +export function matchEvent( + receipt: TransactionReceipt, + name: string, + expectedArgs?: any[], + eventContract: Contract = eventsLib, + emitterAddress?: string +) { + const events = receipt.logs; + + if (events != undefined) { + // match name from list of events in eventContract, when found, compute the sigHash + let sigHash: string | undefined; + for (let contractEvent of Object.keys(eventContract.interface.events)) { + if (contractEvent.startsWith(name) && contractEvent.charAt(name.length) == '(') { + sigHash = keccak256(toUtf8Bytes(contractEvent)); + break; + } + } + // Throw if the sigHash was not found + if (!sigHash) { + logger.throwError( + `Event "${name}" not found in provided contract (default: Events libary). \nAre you sure you're using the right contract?` + ); + } + + // Find the given event in the emitted logs + let invalidParamsButExists = false; + for (let emittedEvent of events) { + // If we find one with the correct sighash, check if it is the one we're looking for + if (emittedEvent.topics[0] == sigHash) { + // If an emitter address is passed, validate that this is indeed the correct emitter, if not, continue + if (emitterAddress) { + if (emittedEvent.address != emitterAddress) continue; + } + const event = eventContract.interface.parseLog(emittedEvent); + // If there are expected arguments, validate them, otherwise, return here + if (expectedArgs) { + if (expectedArgs.length != event.args.length) { + logger.throwError( + `Event "${name}" emitted with correct signature, but expected args are of invalid length` + ); + } + invalidParamsButExists = false; + // Iterate through arguments and check them, if there is a mismatch, continue with the loop + for (let i = 0; i < expectedArgs.length; i++) { + // Parse empty arrays as empty bytes + if (expectedArgs[i].constructor == Array && expectedArgs[i].length == 0) { + expectedArgs[i] = '0x'; + } + + // Break out of the expected args loop if there is a mismatch, this will continue the emitted event loop + if (BigNumber.isBigNumber(event.args[i])) { + if (!event.args[i].eq(BigNumber.from(expectedArgs[i]))) { + invalidParamsButExists = true; + break; + } + } else if (event.args[i].constructor == Array) { + let params = event.args[i]; + let expected = expectedArgs[i]; + if (expected != '0x' && params.length != expected.length) { + invalidParamsButExists = true; + break; + } + for (let j = 0; j < params.length; j++) { + if (BigNumber.isBigNumber(params[j])) { + if (!params[j].eq(BigNumber.from(expected[j]))) { + invalidParamsButExists = true; + break; + } + } else if (params[j] != expected[j]) { + invalidParamsButExists = true; + break; + } + } + if (invalidParamsButExists) break; + } else if (event.args[i] != expectedArgs[i]) { + invalidParamsButExists = true; + break; + } + } + // Return if the for loop did not cause a break, so a match has been found, otherwise proceed with the event loop + if (!invalidParamsButExists) { + return; + } + } else { + return; + } + } + } + // Throw if the event args were not expected or the event was not found in the logs + if (invalidParamsButExists) { + logger.throwError(`Event "${name}" found in logs but with unexpected args`); + } else { + logger.throwError( + `Event "${name}" not found emitted by "${emitterAddress}" in given transaction log` + ); + } + } else { + logger.throwError('No events were emitted'); + } +} + +export function findEvent( + receipt: TransactionReceipt, + name: string, + eventContract: Contract = eventsLib, + emitterAddress?: string +) { + const events = receipt.logs; + + if (events != undefined) { + // match name from list of events in eventContract, when found, compute the sigHash + let sigHash: string | undefined; + for (const contractEvent of Object.keys(eventContract.interface.events)) { + if (contractEvent.startsWith(name) && contractEvent.charAt(name.length) == '(') { + sigHash = keccak256(toUtf8Bytes(contractEvent)); + break; + } + } + // Throw if the sigHash was not found + if (!sigHash) { + logger.throwError( + `Event "${name}" not found in provided contract (default: Events libary). \nAre you sure you're using the right contract?` + ); + } + + for (const emittedEvent of events) { + // If we find one with the correct sighash, check if it is the one we're looking for + if (emittedEvent.topics[0] == sigHash) { + // If an emitter address is passed, validate that this is indeed the correct emitter, if not, continue + if (emitterAddress) { + if (emittedEvent.address != emitterAddress) continue; + } + const event = eventContract.interface.parseLog(emittedEvent); + return event; + } + } + // Throw if the event args were not expected or the event was not found in the logs + logger.throwError( + `Event "${name}" not found emitted by "${emitterAddress}" in given transaction log` + ); + } else { + logger.throwError('No events were emitted'); + } +} + +export function computeContractAddress(deployerAddress: string, nonce: number): string { + const hexNonce = hexlify(nonce); + return '0x' + keccak256(RLP.encode([deployerAddress, hexNonce])).substr(26); +} + +export function getChainId(): number { + return hre.network.config.chainId || HARDHAT_CHAINID; +} + +export function getAbbreviation(handle: string) { + let slice = handle.substr(0, 4); + if (slice.charAt(3) == ' ') { + slice = slice.substr(0, 3); + } + return slice; +} + +export async function waitForTx( + tx: Promise | TransactionResponse, + skipCheck = false +): Promise { + if (!skipCheck) await expect(tx).to.not.be.reverted; + return await (await tx).wait(); +} + +export async function getBlockNumber(): Promise { + return (await helper.getBlockNumber()).toNumber(); +} + +export async function resetFork(): Promise { + await hre.network.provider.request({ + method: 'hardhat_reset', + params: [ + { + forking: { + jsonRpcUrl: process.env.MAINNET_RPC_URL, + blockNumber: 12012081, + }, + }, + ], + }); + console.log('\t> Fork reset'); + + await hre.network.provider.request({ + method: 'evm_setNextBlockTimestamp', + params: [1614290545], // Original block timestamp + 1 + }); + + console.log('\t> Timestamp reset to 1614290545'); +} + +export async function getTimestamp(): Promise { + const blockNumber = await hre.ethers.provider.send('eth_blockNumber', []); + const block = await hre.ethers.provider.send('eth_getBlockByNumber', [blockNumber, false]); + return block.timestamp; +} + +export async function setNextBlockTimestamp(timestamp: number): Promise { + await hre.ethers.provider.send('evm_setNextBlockTimestamp', [timestamp]); +} + +export async function mine(blocks: number): Promise { + for (let i = 0; i < blocks; i++) { + await hre.ethers.provider.send('evm_mine', []); + } +} + +let snapshotId: string = '0x1'; +export async function takeSnapshot() { + snapshotId = await hre.ethers.provider.send('evm_snapshot', []); +} + +export async function revertToSnapshot() { + await hre.ethers.provider.send('evm_revert', [snapshotId]); +} + +export async function cancelWithPermitForAll(nft: string = lensHub.address) { + const nftContract = LensHub__factory.connect(nft, testWallet); + const name = await nftContract.name(); + const nonce = (await nftContract.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getPermitForAllParts( + nft, + name, + testWallet.address, + testWallet.address, + false, + nonce, + MAX_UINT256 + ); + await nftContract.permitForAll(testWallet.address, testWallet.address, false, { + v, + r, + s, + deadline: MAX_UINT256, + }); +} + +export async function getPermitParts( + nft: string, + name: string, + spender: string, + tokenId: BigNumberish, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildPermitParams(nft, name, spender, tokenId, nonce, deadline); + return await getSig(msgParams); +} + +export async function getPermitForAllParts( + nft: string, + name: string, + owner: string, + operator: string, + approved: boolean, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildPermitForAllParams(nft, name, owner, operator, approved, nonce, deadline); + return await getSig(msgParams); +} + +export async function getBurnWithSigparts( + nft: string, + name: string, + tokenId: BigNumberish, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildBurnWithSigParams(nft, name, tokenId, nonce, deadline); + return await getSig(msgParams); +} + +export async function getDelegateBySigParts( + nft: string, + name: string, + delegator: string, + delegatee: string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildDelegateBySigParams(nft, name, delegator, delegatee, nonce, deadline); + return await getSig(msgParams); +} + +const buildDelegateBySigParams = ( + nft: string, + name: string, + delegator: string, + delegatee: string, + nonce: number, + deadline: string +) => ({ + types: { + DelegateBySig: [ + { name: 'delegator', type: 'address' }, + { name: 'delegatee', type: 'address' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: name, + version: '1', + chainId: getChainId(), + verifyingContract: nft, + }, + value: { + delegator: delegator, + delegatee: delegatee, + nonce: nonce, + deadline: deadline, + }, +}); + +export async function getSetFollowModuleWithSigParts( + profileId: BigNumberish, + followModule: string, + followModuleInitData: Bytes | string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildSetFollowModuleWithSigParams( + profileId, + followModule, + followModuleInitData, + nonce, + deadline + ); + return await getSig(msgParams); +} + +export async function getSetDispatcherWithSigParts( + profileId: BigNumberish, + dispatcher: string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildSetDispatcherWithSigParams(profileId, dispatcher, nonce, deadline); + return await getSig(msgParams); +} + +export async function getSetProfileImageURIWithSigParts( + profileId: BigNumberish, + imageURI: string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildSetProfileImageURIWithSigParams(profileId, imageURI, nonce, deadline); + return await getSig(msgParams); +} + +export async function getSetDefaultProfileWithSigParts( + wallet: string, + profileId: BigNumberish, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildSetDefaultProfileWithSigParams(profileId, wallet, nonce, deadline); + return await getSig(msgParams); +} + +export async function getSetFollowNFTURIWithSigParts( + profileId: BigNumberish, + followNFTURI: string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildSetFollowNFTURIWithSigParams(profileId, followNFTURI, nonce, deadline); + return await getSig(msgParams); +} + +export async function getPostWithSigParts( + profileId: BigNumberish, + contentURI: string, + collectModule: string, + collectModuleInitData: Bytes | string, + referenceModule: string, + referenceModuleInitData: Bytes | string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildPostWithSigParams( + profileId, + contentURI, + collectModule, + collectModuleInitData, + referenceModule, + referenceModuleInitData, + nonce, + deadline + ); + return await getSig(msgParams); +} + +export async function getCommentWithSigParts( + profileId: BigNumberish, + contentURI: string, + profileIdPointed: BigNumberish, + pubIdPointed: string, + referenceModuleData: Bytes | string, + collectModule: string, + collectModuleInitData: Bytes | string, + referenceModule: string, + referenceModuleInitData: Bytes | string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildCommentWithSigParams( + profileId, + contentURI, + profileIdPointed, + pubIdPointed, + referenceModuleData, + collectModule, + collectModuleInitData, + referenceModule, + referenceModuleInitData, + nonce, + deadline + ); + return await getSig(msgParams); +} + +export async function getMirrorWithSigParts( + profileId: BigNumberish, + profileIdPointed: BigNumberish, + pubIdPointed: string, + referenceModuleData: Bytes | string, + referenceModule: string, + referenceModuleInitData: Bytes | string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildMirrorWithSigParams( + profileId, + profileIdPointed, + pubIdPointed, + referenceModuleData, + referenceModule, + referenceModuleInitData, + nonce, + deadline + ); + return await getSig(msgParams); +} + +export async function getFollowWithSigParts( + profileIds: string[] | number[], + datas: Bytes[] | string[], + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildFollowWithSigParams(profileIds, datas, nonce, deadline); + return await getSig(msgParams); +} + +export async function getToggleFollowWithSigParts( + profileIds: string[] | number[], + enables: boolean[], + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildToggleFollowWithSigParams(profileIds, enables, nonce, deadline); + return await getSig(msgParams); +} + +export async function getSetProfileMetadataURIWithSigParts( + profileId: string | number, + metadata: string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildSetProfileMetadataURIWithSigParams(profileId, metadata, nonce, deadline); + return await getSig(msgParams); +} + +export async function getCollectWithSigParts( + profileId: BigNumberish, + pubId: string, + data: Bytes | string, + nonce: number, + deadline: string +): Promise<{ v: number; r: string; s: string }> { + const msgParams = buildCollectWithSigParams(profileId, pubId, data, nonce, deadline); + return await getSig(msgParams); +} + +export function expectEqualArrays(actual: BigNumberish[], expected: BigNumberish[]) { + if (actual.length != expected.length) { + logger.throwError( + `${actual} length ${actual.length} does not match ${expected} length ${expect.length}` + ); + } + + let areEquals = true; + for (let i = 0; areEquals && i < actual.length; i++) { + areEquals = BigNumber.from(actual[i]).eq(BigNumber.from(expected[i])); + } + + if (!areEquals) { + logger.throwError(`${actual} does not match ${expected}`); + } +} + +export interface CreateProfileReturningTokenIdStruct { + sender?: Signer; + vars: CreateProfileDataStruct; +} + +export async function createProfileReturningTokenId({ + sender = user, + vars, +}: CreateProfileReturningTokenIdStruct): Promise { + const tokenId = await lensHub.connect(sender).callStatic.createProfile(vars); + await expect(lensHub.connect(sender).createProfile(vars)).to.not.be.reverted; + return tokenId; +} + +export interface FollowDataStruct { + profileIds: BigNumberish[]; + datas: BytesLike[]; +} + +export interface FollowReturningTokenIdsStruct { + sender?: Signer; + vars: FollowDataStruct | FollowWithSigDataStruct; +} + +export async function followReturningTokenIds({ + sender = user, + vars, +}: FollowReturningTokenIdsStruct): Promise { + let tokenIds; + if ('sig' in vars) { + tokenIds = await lensHub.connect(sender).callStatic.followWithSig(vars); + await expect(lensHub.connect(sender).followWithSig(vars)).to.not.be.reverted; + } else { + tokenIds = await lensHub.connect(sender).callStatic.follow(vars.profileIds, vars.datas); + await expect(lensHub.connect(sender).follow(vars.profileIds, vars.datas)).to.not.be.reverted; + } + return tokenIds; +} + +export interface CollectDataStruct { + profileId: BigNumberish; + pubId: BigNumberish; + data: BytesLike; +} + +export interface CollectReturningTokenIdsStruct { + sender?: Signer; + vars: CollectDataStruct | CollectWithSigDataStruct; +} + +export async function collectReturningTokenIds({ + sender = user, + vars, +}: CollectReturningTokenIdsStruct): Promise { + let tokenId; + if ('sig' in vars) { + tokenId = await lensHub.connect(sender).callStatic.collectWithSig(vars); + await expect(lensHub.connect(sender).collectWithSig(vars)).to.not.be.reverted; + } else { + tokenId = await lensHub + .connect(sender) + .callStatic.collect(vars.profileId, vars.pubId, vars.data); + await expect(lensHub.connect(sender).collect(vars.profileId, vars.pubId, vars.data)).to.not.be + .reverted; + } + return tokenId; +} + +export interface CommentReturningTokenIdStruct { + sender?: Signer; + vars: CommentDataStruct | CommentWithSigDataStruct; +} + +export async function commentReturningTokenId({ + sender = user, + vars, +}: CommentReturningTokenIdStruct): Promise { + let tokenId; + if ('sig' in vars) { + tokenId = await lensHub.connect(sender).callStatic.commentWithSig(vars); + await expect(lensHub.connect(sender).commentWithSig(vars)).to.not.be.reverted; + } else { + tokenId = await lensHub.connect(sender).callStatic.comment(vars); + await expect(lensHub.connect(sender).comment(vars)).to.not.be.reverted; + } + return tokenId; +} + +export interface MirrorReturningTokenIdStruct { + sender?: Signer; + vars: MirrorDataStruct | MirrorWithSigDataStruct; +} + +export async function mirrorReturningTokenId({ + sender = user, + vars, +}: MirrorReturningTokenIdStruct): Promise { + let tokenId; + if ('sig' in vars) { + tokenId = await lensHub.connect(sender).callStatic.mirrorWithSig(vars); + await expect(lensHub.connect(sender).mirrorWithSig(vars)).to.not.be.reverted; + } else { + tokenId = await lensHub.connect(sender).callStatic.mirror(vars); + await expect(lensHub.connect(sender).mirror(vars)).to.not.be.reverted; + } + return tokenId; +} + +export interface PostReturningTokenIdStruct { + sender?: Signer; + vars: PostDataStruct | PostWithSigDataStruct; +} + +export async function postReturningTokenId({ + sender = user, + vars, +}: PostReturningTokenIdStruct): Promise { + let tokenId; + if ('sig' in vars) { + tokenId = await lensHub.connect(sender).callStatic.postWithSig(vars); + await expect(lensHub.connect(sender).postWithSig(vars)).to.not.be.reverted; + } else { + tokenId = await lensHub.connect(sender).callStatic.post(vars); + await expect(lensHub.connect(sender).post(vars)).to.not.be.reverted; + } + return tokenId; +} + +export interface TokenUriMetadataAttribute { + trait_type: string; + value: string; +} + +export interface ProfileTokenUriMetadata { + name: string; + description: string; + image: string; + attributes: TokenUriMetadataAttribute[]; +} + +export async function getMetadataFromBase64TokenUri( + tokenUri: string +): Promise { + const splittedTokenUri = tokenUri.split('data:application/json;base64,'); + if (splittedTokenUri.length != 2) { + logger.throwError('Wrong or unrecognized token URI format'); + } else { + const jsonMetadataBase64String = splittedTokenUri[1]; + const jsonMetadataBytes = ethers.utils.base64.decode(jsonMetadataBase64String); + const jsonMetadataString = ethers.utils.toUtf8String(jsonMetadataBytes); + return JSON.parse(jsonMetadataString); + } +} + +export async function getDecodedSvgImage(tokenUriMetadata: ProfileTokenUriMetadata) { + const splittedImage = tokenUriMetadata.image.split('data:image/svg+xml;base64,'); + if (splittedImage.length != 2) { + logger.throwError('Wrong or unrecognized token URI format'); + } else { + return ethers.utils.toUtf8String(ethers.utils.base64.decode(splittedImage[1])); + } +} + +export function loadTestResourceAsUtf8String(relativePathToResouceDir: string) { + return readFileSync(join('test', 'resources', relativePathToResouceDir), 'utf8'); +} + +// Modified from AaveTokenV2 repo +const buildPermitParams = ( + nft: string, + name: string, + spender: string, + tokenId: BigNumberish, + nonce: number, + deadline: string +) => ({ + types: { + Permit: [ + { name: 'spender', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: name, + version: '1', + chainId: getChainId(), + verifyingContract: nft, + }, + value: { + spender: spender, + tokenId: tokenId, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildPermitForAllParams = ( + nft: string, + name: string, + owner: string, + operator: string, + approved: boolean, + nonce: number, + deadline: string +) => ({ + types: { + PermitForAll: [ + { name: 'owner', type: 'address' }, + { name: 'operator', type: 'address' }, + { name: 'approved', type: 'bool' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: name, + version: '1', + chainId: getChainId(), + verifyingContract: nft, + }, + value: { + owner: owner, + operator: operator, + approved: approved, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildBurnWithSigParams = ( + nft: string, + name: string, + tokenId: BigNumberish, + nonce: number, + deadline: string +) => ({ + types: { + BurnWithSig: [ + { name: 'tokenId', type: 'uint256' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: name, + version: '1', + chainId: getChainId(), + verifyingContract: nft, + }, + value: { + tokenId: tokenId, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetFollowModuleWithSigParams = ( + profileId: BigNumberish, + followModule: string, + followModuleInitData: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + SetFollowModuleWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'followModule', type: 'address' }, + { name: 'followModuleInitData', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + followModule: followModule, + followModuleInitData: followModuleInitData, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetDispatcherWithSigParams = ( + profileId: BigNumberish, + dispatcher: string, + nonce: number, + deadline: string +) => ({ + types: { + SetDispatcherWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'dispatcher', type: 'address' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + dispatcher: dispatcher, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetProfileImageURIWithSigParams = ( + profileId: BigNumberish, + imageURI: string, + nonce: number, + deadline: string +) => ({ + types: { + SetProfileImageURIWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'imageURI', type: 'string' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + imageURI: imageURI, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetDefaultProfileWithSigParams = ( + profileId: BigNumberish, + wallet: string, + nonce: number, + deadline: string +) => ({ + types: { + SetDefaultProfileWithSig: [ + { name: 'wallet', type: 'address' }, + { name: 'profileId', type: 'uint256' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + wallet: wallet, + profileId: profileId, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetFollowNFTURIWithSigParams = ( + profileId: BigNumberish, + followNFTURI: string, + nonce: number, + deadline: string +) => ({ + types: { + SetFollowNFTURIWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'followNFTURI', type: 'string' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + followNFTURI: followNFTURI, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildPostWithSigParams = ( + profileId: BigNumberish, + contentURI: string, + collectModule: string, + collectModuleInitData: Bytes | string, + referenceModule: string, + referenceModuleInitData: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + PostWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'contentURI', type: 'string' }, + { name: 'collectModule', type: 'address' }, + { name: 'collectModuleInitData', type: 'bytes' }, + { name: 'referenceModule', type: 'address' }, + { name: 'referenceModuleInitData', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + contentURI: contentURI, + collectModule: collectModule, + collectModuleInitData: collectModuleInitData, + referenceModule: referenceModule, + referenceModuleInitData: referenceModuleInitData, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildCommentWithSigParams = ( + profileId: BigNumberish, + contentURI: string, + profileIdPointed: BigNumberish, + pubIdPointed: string, + referenceModuleData: Bytes | string, + collectModule: string, + collectModuleInitData: Bytes | string, + referenceModule: string, + referenceModuleInitData: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + CommentWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'contentURI', type: 'string' }, + { name: 'profileIdPointed', type: 'uint256' }, + { name: 'pubIdPointed', type: 'uint256' }, + { name: 'referenceModuleData', type: 'bytes' }, + { name: 'collectModule', type: 'address' }, + { name: 'collectModuleInitData', type: 'bytes' }, + { name: 'referenceModule', type: 'address' }, + { name: 'referenceModuleInitData', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + contentURI: contentURI, + profileIdPointed: profileIdPointed, + pubIdPointed: pubIdPointed, + referenceModuleData: referenceModuleData, + collectModule: collectModule, + collectModuleInitData: collectModuleInitData, + referenceModule: referenceModule, + referenceModuleInitData: referenceModuleInitData, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildMirrorWithSigParams = ( + profileId: BigNumberish, + profileIdPointed: BigNumberish, + pubIdPointed: string, + referenceModuleData: Bytes | string, + referenceModule: string, + referenceModuleInitData: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + MirrorWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'profileIdPointed', type: 'uint256' }, + { name: 'pubIdPointed', type: 'uint256' }, + { name: 'referenceModuleData', type: 'bytes' }, + { name: 'referenceModule', type: 'address' }, + { name: 'referenceModuleInitData', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + profileIdPointed: profileIdPointed, + pubIdPointed: pubIdPointed, + referenceModuleData: referenceModuleData, + referenceModule: referenceModule, + referenceModuleInitData: referenceModuleInitData, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildFollowWithSigParams = ( + profileIds: string[] | number[], + datas: Bytes[] | string[], + nonce: number, + deadline: string +) => ({ + types: { + FollowWithSig: [ + { name: 'profileIds', type: 'uint256[]' }, + { name: 'datas', type: 'bytes[]' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileIds: profileIds, + datas: datas, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildToggleFollowWithSigParams = ( + profileIds: string[] | number[], + enables: boolean[], + nonce: number, + deadline: string +) => ({ + types: { + ToggleFollowWithSig: [ + { name: 'profileIds', type: 'uint256[]' }, + { name: 'enables', type: 'bool[]' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: LENS_PERIPHERY_NAME, + version: '1', + chainId: getChainId(), + verifyingContract: lensPeriphery.address, + }, + value: { + profileIds: profileIds, + enables: enables, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetProfileMetadataURIWithSigParams = ( + profileId: string | number, + metadata: string, + nonce: number, + deadline: string +) => ({ + types: { + SetProfileMetadataURIWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'metadata', type: 'string' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: LENS_PERIPHERY_NAME, + version: '1', + chainId: getChainId(), + verifyingContract: lensPeriphery.address, + }, + value: { + profileId: profileId, + metadata: metadata, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildCollectWithSigParams = ( + profileId: BigNumberish, + pubId: string, + data: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + CollectWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'pubId', type: 'uint256' }, + { name: 'data', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + pubId: pubId, + data: data, + nonce: nonce, + deadline: deadline, + }, +}); + +async function getSig(msgParams: { + domain: any; + types: any; + value: any; +}): Promise<{ v: number; r: string; s: string }> { + const sig = await testWallet._signTypedData(msgParams.domain, msgParams.types, msgParams.value); + return utils.splitSignature(sig); +} + +function domain(): { name: string; version: string; chainId: number; verifyingContract: string } { + return { + name: LENS_HUB_NFT_NAME, + version: '1', + chainId: getChainId(), + verifyingContract: lensHub.address, + }; +} diff --git a/lens-protocol/core/test/hub/interactions/collecting.spec.ts b/lens-protocol/core/test/hub/interactions/collecting.spec.ts new file mode 100644 index 0000000..9ed6fe2 --- /dev/null +++ b/lens-protocol/core/test/hub/interactions/collecting.spec.ts @@ -0,0 +1,543 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { CollectNFT__factory, FollowNFT__factory } from '../../../typechain-types'; +import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { + cancelWithPermitForAll, + collectReturningTokenIds, + getAbbreviation, + getCollectWithSigParts, + getTimestamp, +} from '../../helpers/utils'; +import { + lensHub, + freeCollectModule, + FIRST_PROFILE_ID, + governance, + makeSuiteCleanRoom, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + testWallet, + userAddress, + userTwo, + userTwoAddress, + MOCK_FOLLOW_NFT_URI, + abiCoder, + user, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Collecting', function () { + beforeEach(async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + context('Generic', function () { + context('Negatives', function () { + it('UserTwo should fail to collect without being a follower', async function () { + await expect(lensHub.connect(userTwo).collect(FIRST_PROFILE_ID, 1, [])).to.be.revertedWith( + ERRORS.FOLLOW_INVALID + ); + }); + + it('user two should follow, then transfer the followNFT and fail to collect', async function () { + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const followNftAddr = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + await expect( + FollowNFT__factory.connect(followNftAddr, userTwo).transferFrom( + userTwoAddress, + userAddress, + 1 + ) + ).to.not.be.reverted; + await expect(lensHub.connect(userTwo).collect(FIRST_PROFILE_ID, 1, [])).to.be.revertedWith( + ERRORS.FOLLOW_INVALID + ); + }); + }); + + context('Scenarios', function () { + it('Collecting should work if the collector is the publication owner even when he is not following himself and follow NFT was not deployed', async function () { + await expect(lensHub.collect(FIRST_PROFILE_ID, 1, [])).to.not.be.reverted; + }); + + it('Collecting should work if the collector is the publication owner even when he is not following himself and follow NFT was deployed', async function () { + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const followNFT = FollowNFT__factory.connect( + await lensHub.getFollowNFT(FIRST_PROFILE_ID), + user + ); + + await expect(followNFT.transferFrom(userAddress, userTwoAddress, 1)).to.not.be.reverted; + + await expect(lensHub.collect(FIRST_PROFILE_ID, 1, [])).to.not.be.reverted; + }); + + it('Should return the expected token IDs when collecting publications', async function () { + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + await expect( + lensHub.connect(testWallet).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + expect( + await collectReturningTokenIds({ + vars: { + profileId: FIRST_PROFILE_ID, + pubId: 1, + data: [], + }, + }) + ).to.eq(1); + + expect( + await collectReturningTokenIds({ + sender: userTwo, + vars: { + profileId: FIRST_PROFILE_ID, + pubId: 1, + data: [], + }, + }) + ).to.eq(2); + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getCollectWithSigParts( + FIRST_PROFILE_ID, + '1', + [], + nonce, + MAX_UINT256 + ); + expect( + await collectReturningTokenIds({ + vars: { + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }, + }) + ).to.eq(3); + + expect( + await collectReturningTokenIds({ + vars: { + profileId: FIRST_PROFILE_ID, + pubId: 1, + data: [], + }, + }) + ).to.eq(4); + }); + + it('UserTwo should follow, then collect, receive a collect NFT with the expected properties', async function () { + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + await expect(lensHub.connect(userTwo).collect(FIRST_PROFILE_ID, 1, [])).to.not.be.reverted; + const timestamp = await getTimestamp(); + + const collectNFTAddr = await lensHub.getCollectNFT(FIRST_PROFILE_ID, 1); + expect(collectNFTAddr).to.not.eq(ZERO_ADDRESS); + const collectNFT = CollectNFT__factory.connect(collectNFTAddr, userTwo); + const id = await collectNFT.tokenOfOwnerByIndex(userTwoAddress, 0); + const name = await collectNFT.name(); + const symbol = await collectNFT.symbol(); + const pointer = await collectNFT.getSourcePublicationPointer(); + const owner = await collectNFT.ownerOf(id); + const mintTimestamp = await collectNFT.mintTimestampOf(id); + const tokenData = await collectNFT.tokenDataOf(id); + + const expectedName = MOCK_PROFILE_HANDLE + '-Collect-' + '1'; + const expectedSymbol = getAbbreviation(MOCK_PROFILE_HANDLE) + '-Cl-' + '1'; + + expect(id).to.eq(1); + expect(name).to.eq(expectedName); + expect(symbol).to.eq(expectedSymbol); + expect(pointer[0]).to.eq(FIRST_PROFILE_ID); + expect(pointer[1]).to.eq(1); + expect(owner).to.eq(userTwoAddress); + expect(tokenData.owner).to.eq(userTwoAddress); + expect(tokenData.mintTimestamp).to.eq(timestamp); + expect(mintTimestamp).to.eq(timestamp); + }); + + it('UserTwo should follow, then mirror, then collect on their mirror, receive a collect NFT with expected properties', async function () { + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const secondProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(userTwo).createProfile({ + to: userTwoAddress, + handle: 'mockhandle', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(userTwo).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(userTwo).collect(secondProfileId, 1, [])).to.not.be.reverted; + + const collectNFTAddr = await lensHub.getCollectNFT(FIRST_PROFILE_ID, 1); + expect(collectNFTAddr).to.not.eq(ZERO_ADDRESS); + const collectNFT = CollectNFT__factory.connect(collectNFTAddr, userTwo); + const id = await collectNFT.tokenOfOwnerByIndex(userTwoAddress, 0); + const name = await collectNFT.name(); + const symbol = await collectNFT.symbol(); + const pointer = await collectNFT.getSourcePublicationPointer(); + + const expectedName = MOCK_PROFILE_HANDLE + '-Collect-' + '1'; + const expectedSymbol = getAbbreviation(MOCK_PROFILE_HANDLE) + '-Cl-' + '1'; + expect(id).to.eq(1); + expect(name).to.eq(expectedName); + expect(symbol).to.eq(expectedSymbol); + expect(pointer[0]).to.eq(FIRST_PROFILE_ID); + expect(pointer[1]).to.eq(1); + }); + + it('UserTwo should follow, then mirror, mirror their mirror then collect on their latest mirror, receive a collect NFT with expected properties', async function () { + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const secondProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(userTwo).createProfile({ + to: userTwoAddress, + handle: 'mockhandle', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(userTwo).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(userTwo).mirror({ + profileId: secondProfileId, + profileIdPointed: secondProfileId, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(userTwo).collect(secondProfileId, 2, [])).to.not.be.reverted; + + const collectNFTAddr = await lensHub.getCollectNFT(FIRST_PROFILE_ID, 1); + expect(collectNFTAddr).to.not.eq(ZERO_ADDRESS); + const collectNFT = CollectNFT__factory.connect(collectNFTAddr, userTwo); + const id = await collectNFT.tokenOfOwnerByIndex(userTwoAddress, 0); + const name = await collectNFT.name(); + const symbol = await collectNFT.symbol(); + const pointer = await collectNFT.getSourcePublicationPointer(); + + const expectedName = MOCK_PROFILE_HANDLE + '-Collect-' + '1'; + const expectedSymbol = getAbbreviation(MOCK_PROFILE_HANDLE) + '-Cl-' + '1'; + expect(id).to.eq(1); + expect(name).to.eq(expectedName); + expect(symbol).to.eq(expectedSymbol); + expect(pointer[0]).to.eq(FIRST_PROFILE_ID); + expect(pointer[1]).to.eq(1); + }); + }); + }); + + context('Meta-tx', function () { + context('Negatives', function () { + it('TestWallet should fail to collect with sig with signature deadline mismatch', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getCollectWithSigParts(FIRST_PROFILE_ID, '1', [], nonce, '0'); + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should fail to collect with sig with invalid deadline', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getCollectWithSigParts(FIRST_PROFILE_ID, '1', [], nonce, '0'); + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: '0', + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('TestWallet should fail to collect with sig with invalid nonce', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getCollectWithSigParts( + FIRST_PROFILE_ID, + '1', + [], + nonce + 1, + MAX_UINT256 + ); + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should fail to collect with sig without being a follower', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getCollectWithSigParts( + FIRST_PROFILE_ID, + '1', + [], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('TestWallet should sign attempt to collect with sig, cancel via empty permitForAll, fail to collect with sig', async function () { + await expect( + lensHub.connect(testWallet).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getCollectWithSigParts( + FIRST_PROFILE_ID, + '1', + [], + nonce, + MAX_UINT256 + ); + + await cancelWithPermitForAll(); + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + it('TestWallet should follow, then collect with sig, receive a collect NFT with expected properties', async function () { + await expect( + lensHub.connect(testWallet).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getCollectWithSigParts( + FIRST_PROFILE_ID, + '1', + [], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const collectNFTAddr = await lensHub.getCollectNFT(FIRST_PROFILE_ID, 1); + expect(collectNFTAddr).to.not.eq(ZERO_ADDRESS); + const collectNFT = CollectNFT__factory.connect(collectNFTAddr, userTwo); + const id = await collectNFT.tokenOfOwnerByIndex(testWallet.address, 0); + const name = await collectNFT.name(); + const symbol = await collectNFT.symbol(); + const pointer = await collectNFT.getSourcePublicationPointer(); + + const expectedName = MOCK_PROFILE_HANDLE + '-Collect-' + '1'; + const expectedSymbol = getAbbreviation(MOCK_PROFILE_HANDLE) + '-Cl-' + '1'; + expect(id).to.eq(1); + expect(name).to.eq(expectedName); + expect(symbol).to.eq(expectedSymbol); + expect(pointer[0]).to.eq(FIRST_PROFILE_ID); + expect(pointer[1]).to.eq(1); + }); + + it('TestWallet should follow, mirror, then collect with sig on their mirror', async function () { + await expect( + lensHub.connect(testWallet).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const secondProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: 'mockhandle', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getCollectWithSigParts( + secondProfileId.toString(), + '1', + [], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: secondProfileId, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const collectNFTAddr = await lensHub.getCollectNFT(FIRST_PROFILE_ID, 1); + expect(collectNFTAddr).to.not.eq(ZERO_ADDRESS); + const collectNFT = CollectNFT__factory.connect(collectNFTAddr, userTwo); + const id = await collectNFT.tokenOfOwnerByIndex(testWallet.address, 0); + const name = await collectNFT.name(); + const symbol = await collectNFT.symbol(); + const pointer = await collectNFT.getSourcePublicationPointer(); + + const expectedName = MOCK_PROFILE_HANDLE + '-Collect-' + '1'; + const expectedSymbol = getAbbreviation(MOCK_PROFILE_HANDLE) + '-Cl-' + '1'; + expect(id).to.eq(1); + expect(name).to.eq(expectedName); + expect(symbol).to.eq(expectedSymbol); + expect(pointer[0]).to.eq(FIRST_PROFILE_ID); + expect(pointer[1]).to.eq(1); + }); + }); + }); +}); diff --git a/lens-protocol/core/test/hub/interactions/following.spec.ts b/lens-protocol/core/test/hub/interactions/following.spec.ts new file mode 100644 index 0000000..d7e494f --- /dev/null +++ b/lens-protocol/core/test/hub/interactions/following.spec.ts @@ -0,0 +1,364 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { BigNumber } from 'ethers'; +import { FollowNFT__factory } from '../../../typechain-types'; +import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { + cancelWithPermitForAll, + expectEqualArrays, + followReturningTokenIds, + getAbbreviation, + getFollowWithSigParts, + getTimestamp, +} from '../../helpers/utils'; +import { + lensHub, + FIRST_PROFILE_ID, + makeSuiteCleanRoom, + MOCK_PROFILE_HANDLE, + testWallet, + user, + userTwo, + userTwoAddress, + MOCK_PROFILE_URI, + userAddress, + MOCK_FOLLOW_NFT_URI, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Following', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + context('Generic', function () { + context('Negatives', function () { + it('UserTwo should fail to follow a nonexistent profile', async function () { + await expect( + lensHub.connect(userTwo).follow([FIRST_PROFILE_ID + 1], [[]]) + ).to.be.revertedWith(ERRORS.TOKEN_DOES_NOT_EXIST); + }); + + it('UserTwo should fail to follow with array mismatch', async function () { + await expect( + lensHub.connect(userTwo).follow([FIRST_PROFILE_ID, FIRST_PROFILE_ID], [[]]) + ).to.be.revertedWith(ERRORS.ARRAY_MISMATCH); + }); + + it('UserTwo should fail to follow a profile that has been burned', async function () { + await expect(lensHub.burn(FIRST_PROFILE_ID)).to.not.be.reverted; + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.be.revertedWith( + ERRORS.TOKEN_DOES_NOT_EXIST + ); + }); + }); + + context('Scenarios', function () { + it('UserTwo should follow profile 1, receive a followNFT with ID 1, followNFT properties should be correct', async function () { + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const timestamp = await getTimestamp(); + + const followNFTAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNFT = FollowNFT__factory.connect(followNFTAddress, user); + expect(followNFT.address).to.not.eq(ZERO_ADDRESS); + const id = await followNFT.tokenOfOwnerByIndex(userTwoAddress, 0); + const name = await followNFT.name(); + const symbol = await followNFT.symbol(); + const owner = await followNFT.ownerOf(id); + const mintTimestamp = await followNFT.mintTimestampOf(id); + const followNFTURI = await followNFT.tokenURI(id); + const tokenData = await followNFT.tokenDataOf(id); + + expect(id).to.eq(1); + expect(name).to.eq(MOCK_PROFILE_HANDLE + '-Follower'); + expect(symbol).to.eq(getAbbreviation(MOCK_PROFILE_HANDLE) + '-Fl'); + expect(owner).to.eq(userTwoAddress); + expect(tokenData.owner).to.eq(userTwoAddress); + expect(tokenData.mintTimestamp).to.eq(timestamp); + expect(followNFTURI).to.eq(MOCK_FOLLOW_NFT_URI); + expect(mintTimestamp).to.eq(timestamp); + }); + + it('UserTwo should follow profile 1 twice, receiving followNFTs with IDs 1 and 2', async function () { + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const followNFTAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNFT = FollowNFT__factory.connect(followNFTAddress, user); + const idOne = await followNFT.tokenOfOwnerByIndex(userTwoAddress, 0); + const idTwo = await followNFT.tokenOfOwnerByIndex(userTwoAddress, 1); + expect(idOne).to.eq(1); + expect(idTwo).to.eq(2); + }); + + it('UserTwo should follow profile 1 3 times in the same call, receive IDs 1,2 and 3', async function () { + await expect( + lensHub + .connect(userTwo) + .follow([FIRST_PROFILE_ID, FIRST_PROFILE_ID, FIRST_PROFILE_ID], [[], [], []]) + ).to.not.be.reverted; + const followNFTAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNFT = FollowNFT__factory.connect(followNFTAddress, user); + const idOne = await followNFT.tokenOfOwnerByIndex(userTwoAddress, 0); + const idTwo = await followNFT.tokenOfOwnerByIndex(userTwoAddress, 1); + const idThree = await followNFT.tokenOfOwnerByIndex(userTwoAddress, 2); + expect(idOne).to.eq(1); + expect(idTwo).to.eq(2); + expect(idThree).to.eq(3); + }); + + it('Should return the expected token IDs when following profiles', async function () { + expectEqualArrays( + await followReturningTokenIds({ + vars: { + profileIds: [FIRST_PROFILE_ID, FIRST_PROFILE_ID], + datas: [[], []], + }, + }), + [1, 2] + ); + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getFollowWithSigParts( + [FIRST_PROFILE_ID], + [[]], + nonce, + MAX_UINT256 + ); + expectEqualArrays( + await followReturningTokenIds({ + vars: { + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }, + }), + [3] + ); + + expectEqualArrays( + await followReturningTokenIds({ + sender: userTwo, + vars: { + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + }, + }), + [4] + ); + + expectEqualArrays( + await followReturningTokenIds({ + vars: { + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + }, + }), + [5] + ); + }); + }); + }); + + context('Meta-tx', function () { + context('Negatives', function () { + it('TestWallet should fail to follow with sig with signature deadline mismatch', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getFollowWithSigParts([FIRST_PROFILE_ID], [[]], nonce, '0'); + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should fail to follow with sig with invalid deadline', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getFollowWithSigParts([FIRST_PROFILE_ID], [[]], nonce, '0'); + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + sig: { + v, + r, + s, + deadline: '0', + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('TestWallet should fail to follow with sig with invalid nonce', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getFollowWithSigParts( + [FIRST_PROFILE_ID], + [[]], + nonce + 1, + MAX_UINT256 + ); + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should fail to follow a nonexistent profile with sig', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getFollowWithSigParts( + [FIRST_PROFILE_ID + 1], + [[]], + nonce, + MAX_UINT256 + ); + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID + 1], + datas: [[]], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.TOKEN_DOES_NOT_EXIST); + }); + + it('TestWallet should sign attempt to follow with sig, cancel with empty permitForAll, then fail to follow with sig', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getFollowWithSigParts( + [FIRST_PROFILE_ID], + [[]], + nonce, + MAX_UINT256 + ); + + await cancelWithPermitForAll(); + + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + it('TestWallet should follow profile 1 with sig, receive a follow NFT with ID 1, follow NFT name and symbol should be correct', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getFollowWithSigParts( + [FIRST_PROFILE_ID], + [[]], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const followNFTAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNFT = FollowNFT__factory.connect(followNFTAddress, user); + const id = await followNFT.tokenOfOwnerByIndex(testWallet.address, 0); + expect(id).to.eq(1); + const name = await followNFT.name(); + const symbol = await followNFT.symbol(); + expect(name).to.eq(MOCK_PROFILE_HANDLE + '-Follower'); + expect(symbol).to.eq(getAbbreviation(MOCK_PROFILE_HANDLE) + '-Fl'); + }); + + it('TestWallet should follow profile 1 with sig twice in the same call, receive follow NFTs with IDs 1 and 2', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getFollowWithSigParts( + [FIRST_PROFILE_ID, FIRST_PROFILE_ID], + [[], []], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID, FIRST_PROFILE_ID], + datas: [[], []], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const followNFTAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNFT = FollowNFT__factory.connect(followNFTAddress, user); + const idOne = await followNFT.tokenOfOwnerByIndex(testWallet.address, 0); + const idTwo = await followNFT.tokenOfOwnerByIndex(testWallet.address, 1); + expect(idOne).to.eq(1); + expect(idTwo).to.eq(2); + const name = await followNFT.name(); + const symbol = await followNFT.symbol(); + expect(name).to.eq(MOCK_PROFILE_HANDLE + '-Follower'); + expect(symbol).to.eq(getAbbreviation(MOCK_PROFILE_HANDLE) + '-Fl'); + }); + }); + }); +}); diff --git a/lens-protocol/core/test/hub/interactions/governance.spec.ts b/lens-protocol/core/test/hub/interactions/governance.spec.ts new file mode 100644 index 0000000..0ade3ce --- /dev/null +++ b/lens-protocol/core/test/hub/interactions/governance.spec.ts @@ -0,0 +1,55 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { ERRORS } from '../../helpers/errors'; +import { governance, lensHub, makeSuiteCleanRoom, userAddress } from '../../__setup.spec'; + +makeSuiteCleanRoom('Governance Functions', function () { + context('Negatives', function () { + it('User should not be able to call governance functions', async function () { + await expect(lensHub.setGovernance(userAddress)).to.be.revertedWith(ERRORS.NOT_GOVERNANCE); + await expect(lensHub.whitelistFollowModule(userAddress, true)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE + ); + await expect(lensHub.whitelistReferenceModule(userAddress, true)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE + ); + await expect(lensHub.whitelistCollectModule(userAddress, true)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE + ); + }); + }); + + context('Scenarios', function () { + it('Governance should successfully whitelist and unwhitelist modules', async function () { + await expect( + lensHub.connect(governance).whitelistFollowModule(userAddress, true) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistReferenceModule(userAddress, true) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistCollectModule(userAddress, true) + ).to.not.be.reverted; + expect(await lensHub.isFollowModuleWhitelisted(userAddress)).to.eq(true); + expect(await lensHub.isReferenceModuleWhitelisted(userAddress)).to.eq(true); + expect(await lensHub.isCollectModuleWhitelisted(userAddress)).to.eq(true); + + await expect( + lensHub.connect(governance).whitelistFollowModule(userAddress, false) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistReferenceModule(userAddress, false) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistCollectModule(userAddress, false) + ).to.not.be.reverted; + expect(await lensHub.isFollowModuleWhitelisted(userAddress)).to.eq(false); + expect(await lensHub.isReferenceModuleWhitelisted(userAddress)).to.eq(false); + expect(await lensHub.isCollectModuleWhitelisted(userAddress)).to.eq(false); + }); + + it('Governance should successfully change the governance address', async function () { + await expect(lensHub.connect(governance).setGovernance(userAddress)).to.not.be.reverted; + }); + }); +}); diff --git a/lens-protocol/core/test/hub/interactions/multi-state-hub.spec.ts b/lens-protocol/core/test/hub/interactions/multi-state-hub.spec.ts new file mode 100644 index 0000000..ef5c4f0 --- /dev/null +++ b/lens-protocol/core/test/hub/interactions/multi-state-hub.spec.ts @@ -0,0 +1,1926 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { + getCollectWithSigParts, + getCommentWithSigParts, + getFollowWithSigParts, + getMirrorWithSigParts, + getPostWithSigParts, + getSetDispatcherWithSigParts, + getSetFollowModuleWithSigParts, + getSetFollowNFTURIWithSigParts, + getSetProfileImageURIWithSigParts, + ProtocolState, +} from '../../helpers/utils'; +import { + freeCollectModule, + FIRST_PROFILE_ID, + governance, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + testWallet, + userAddress, + userTwoAddress, + abiCoder, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Multi-State Hub', function () { + context('Common', function () { + context('Negatives', function () { + it('User should fail to set the state on the hub', async function () { + await expect(lensHub.setState(ProtocolState.Paused)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE_OR_EMERGENCY_ADMIN + ); + await expect(lensHub.setState(ProtocolState.Unpaused)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE_OR_EMERGENCY_ADMIN + ); + await expect(lensHub.setState(ProtocolState.PublishingPaused)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE_OR_EMERGENCY_ADMIN + ); + }); + + it('User should fail to set the emergency admin', async function () { + await expect(lensHub.setEmergencyAdmin(userAddress)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE + ); + }); + + it('Governance should set user as emergency admin, user should fail to set protocol state to Unpaused', async function () { + await expect(lensHub.connect(governance).setEmergencyAdmin(userAddress)).to.not.be.reverted; + await expect(lensHub.setState(ProtocolState.Unpaused)).to.be.revertedWith( + ERRORS.EMERGENCY_ADMIN_CANNOT_UNPAUSE + ); + }); + + it('Governance should set user as emergency admin, user should fail to set protocol state to PublishingPaused or Paused from Paused', async function () { + await expect(lensHub.connect(governance).setEmergencyAdmin(userAddress)).to.not.be.reverted; + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + await expect(lensHub.setState(ProtocolState.PublishingPaused)).to.be.revertedWith( + ERRORS.PAUSED + ); + await expect(lensHub.setState(ProtocolState.Paused)).to.be.revertedWith(ERRORS.PAUSED); + }); + }); + + context('Scenarios', function () { + it('Governance should set user as emergency admin, user sets protocol state but fails to set emergency admin, governance sets emergency admin to the zero address, user fails to set protocol state', async function () { + await expect(lensHub.connect(governance).setEmergencyAdmin(userAddress)).to.not.be.reverted; + + await expect(lensHub.setState(ProtocolState.PublishingPaused)).to.not.be.reverted; + await expect(lensHub.setState(ProtocolState.Paused)).to.not.be.reverted; + await expect(lensHub.setEmergencyAdmin(ZERO_ADDRESS)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE + ); + + await expect( + lensHub.connect(governance).setEmergencyAdmin(ZERO_ADDRESS) + ).to.not.be.reverted; + + await expect(lensHub.setState(ProtocolState.Paused)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE_OR_EMERGENCY_ADMIN + ); + await expect(lensHub.setState(ProtocolState.PublishingPaused)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE_OR_EMERGENCY_ADMIN + ); + await expect(lensHub.setState(ProtocolState.Unpaused)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE_OR_EMERGENCY_ADMIN + ); + }); + + it('Governance should set the protocol state, fetched protocol state should be accurate', async function () { + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + expect(await lensHub.getState()).to.eq(ProtocolState.Paused); + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + expect(await lensHub.getState()).to.eq(ProtocolState.PublishingPaused); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + expect(await lensHub.getState()).to.eq(ProtocolState.Unpaused); + }); + + it('Governance should set user as emergency admin, user should set protocol state to PublishingPaused, then Paused, then fail to set it to PublishingPaused', async function () { + await expect(lensHub.connect(governance).setEmergencyAdmin(userAddress)).to.not.be.reverted; + + await expect(lensHub.setState(ProtocolState.PublishingPaused)).to.not.be.reverted; + await expect(lensHub.setState(ProtocolState.Paused)).to.not.be.reverted; + await expect(lensHub.setState(ProtocolState.PublishingPaused)).to.be.revertedWith( + ERRORS.PAUSED + ); + }); + + it('Governance should set user as emergency admin, user should set protocol state to PublishingPaused, then set it to PublishingPaused again without reverting', async function () { + await expect(lensHub.connect(governance).setEmergencyAdmin(userAddress)).to.not.be.reverted; + + await expect(lensHub.setState(ProtocolState.PublishingPaused)).to.not.be.reverted; + await expect(lensHub.setState(ProtocolState.PublishingPaused)).to.not.be.reverted; + }); + }); + }); + + context('Paused State', function () { + context('Scenarios', async function () { + it('User should create a profile, governance should pause the hub, transferring the profile should fail', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect( + lensHub.transferFrom(userAddress, userTwoAddress, FIRST_PROFILE_ID) + ).to.be.revertedWith(ERRORS.PAUSED); + }); + + it('Governance should pause the hub, profile creation should fail, then governance unpauses the hub and profile creation should work', async function () { + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, setting follow module should fail, then governance unpauses the hub and setting follow module should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect( + lensHub.setFollowModule(FIRST_PROFILE_ID, ZERO_ADDRESS, []) + ).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.setFollowModule(FIRST_PROFILE_ID, ZERO_ADDRESS, []) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, setting follow module with sig should fail, then governance unpauses the hub and setting follow module with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getSetFollowModuleWithSigParts( + FIRST_PROFILE_ID, + ZERO_ADDRESS, + [], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.setFollowModuleWithSig({ + profileId: FIRST_PROFILE_ID, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.setFollowModuleWithSig({ + profileId: FIRST_PROFILE_ID, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, setting dispatcher should fail, then governance unpauses the hub and setting dispatcher should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect(lensHub.setDispatcher(FIRST_PROFILE_ID, userTwoAddress)).to.be.revertedWith( + ERRORS.PAUSED + ); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect(lensHub.setDispatcher(FIRST_PROFILE_ID, userTwoAddress)).to.not.be.reverted; + }); + + it('Governance should pause the hub, setting dispatcher with sig should fail, then governance unpauses the hub and setting dispatcher with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDispatcherWithSigParts( + FIRST_PROFILE_ID, + userTwoAddress, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.setDispatcherWithSig({ + profileId: FIRST_PROFILE_ID, + dispatcher: userTwoAddress, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.setDispatcherWithSig({ + profileId: FIRST_PROFILE_ID, + dispatcher: userTwoAddress, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, setting profile URI should fail, then governance unpauses the hub and setting profile URI should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect(lensHub.setProfileImageURI(FIRST_PROFILE_ID, MOCK_URI)).to.be.revertedWith( + ERRORS.PAUSED + ); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect(lensHub.setProfileImageURI(FIRST_PROFILE_ID, MOCK_URI)).to.not.be.reverted; + }); + + it('Governance should pause the hub, setting profile URI with sig should fail, then governance unpauses the hub and setting profile URI should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetProfileImageURIWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.setProfileImageURIWithSig({ + profileId: FIRST_PROFILE_ID, + imageURI: MOCK_URI, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.setProfileImageURIWithSig({ + profileId: FIRST_PROFILE_ID, + imageURI: MOCK_URI, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, setting follow NFT URI should fail, then governance unpauses the hub and setting follow NFT URI should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect(lensHub.setFollowNFTURI(FIRST_PROFILE_ID, MOCK_URI)).to.be.revertedWith( + ERRORS.PAUSED + ); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect(lensHub.setFollowNFTURI(FIRST_PROFILE_ID, MOCK_URI)).to.not.be.reverted; + }); + + it('Governance should pause the hub, setting follow NFT URI with sig should fail, then governance unpauses the hub and setting follow NFT URI should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetFollowNFTURIWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.setFollowNFTURIWithSig({ + profileId: FIRST_PROFILE_ID, + followNFTURI: MOCK_URI, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.setFollowNFTURIWithSig({ + profileId: FIRST_PROFILE_ID, + followNFTURI: MOCK_URI, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, posting should fail, then governance unpauses the hub and posting should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, posting with sig should fail, then governance unpauses the hub and posting with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, commenting should fail, then governance unpauses the hub and commenting should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, commenting with sig should fail, then governance unpauses the hub and commenting with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, mirroring should fail, then governance unpauses the hub and mirroring should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, mirroring with sig should fail, then governance unpauses the hub and mirroring with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, burning should fail, then governance unpauses the hub and burning should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect(lensHub.burn(FIRST_PROFILE_ID)).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect(lensHub.burn(FIRST_PROFILE_ID)).to.not.be.reverted; + }); + + it('Governance should pause the hub, following should fail, then governance unpauses the hub and following should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + }); + + it('Governance should pause the hub, following with sig should fail, then governance unpauses the hub and following with sig should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getFollowWithSigParts( + [FIRST_PROFILE_ID], + [[]], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause the hub, collecting should fail, then governance unpauses the hub and collecting should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + await expect(lensHub.collect(FIRST_PROFILE_ID, 1, [])).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect(lensHub.collect(FIRST_PROFILE_ID, 1, [])).to.not.be.reverted; + }); + + it('Governance should pause the hub, collecting with sig should fail, then governance unpauses the hub and collecting with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + await expect(lensHub.connect(governance).setState(ProtocolState.Paused)).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getCollectWithSigParts( + FIRST_PROFILE_ID, + '1', + [], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + }); + }); + + context('PublishingPaused State', function () { + context('Scenarios', async function () { + it('Governance should pause publishing, profile creation should work', async function () { + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, setting follow module should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect( + lensHub.setFollowModule(FIRST_PROFILE_ID, ZERO_ADDRESS, []) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, setting follow module with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getSetFollowModuleWithSigParts( + FIRST_PROFILE_ID, + ZERO_ADDRESS, + [], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.setFollowModuleWithSig({ + profileId: FIRST_PROFILE_ID, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, setting dispatcher should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect(lensHub.setDispatcher(FIRST_PROFILE_ID, userTwoAddress)).to.not.be.reverted; + }); + + it('Governance should pause publishing, setting dispatcher with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDispatcherWithSigParts( + FIRST_PROFILE_ID, + userTwoAddress, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.setDispatcherWithSig({ + profileId: FIRST_PROFILE_ID, + dispatcher: userTwoAddress, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, setting profile URI should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect(lensHub.setProfileImageURI(FIRST_PROFILE_ID, MOCK_URI)).to.not.be.reverted; + }); + + it('Governance should pause publishing, setting profile URI with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetProfileImageURIWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.setProfileImageURIWithSig({ + profileId: FIRST_PROFILE_ID, + imageURI: MOCK_URI, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, posting should fail, then governance unpauses the hub and posting should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, posting with sig should fail, then governance unpauses the hub and posting with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, commenting should fail, then governance unpauses the hub and commenting should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, commenting with sig should fail, then governance unpauses the hub and commenting with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, mirroring should fail, then governance unpauses the hub and mirroring should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, mirroring with sig should fail, then governance unpauses the hub and mirroring with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PUBLISHING_PAUSED); + + await expect( + lensHub.connect(governance).setState(ProtocolState.Unpaused) + ).to.not.be.reverted; + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, burning should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect(lensHub.burn(FIRST_PROFILE_ID)).to.not.be.reverted; + }); + + it('Governance should pause publishing, following should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + }); + + it('Governance should pause publishing, following with sig should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getFollowWithSigParts( + [FIRST_PROFILE_ID], + [[]], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.followWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + datas: [[]], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + + it('Governance should pause publishing, collecting should work', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + await expect(lensHub.collect(FIRST_PROFILE_ID, 1, [])).to.not.be.reverted; + }); + + it('Governance should pause publishing, collecting with sig should work', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getCollectWithSigParts( + FIRST_PROFILE_ID, + '1', + [], + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.collectWithSig({ + collector: testWallet.address, + profileId: FIRST_PROFILE_ID, + pubId: '1', + data: [], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + }); + }); + }); +}); diff --git a/lens-protocol/core/test/hub/interactions/publishing-comments.spec.ts b/lens-protocol/core/test/hub/interactions/publishing-comments.spec.ts new file mode 100644 index 0000000..b8d671d --- /dev/null +++ b/lens-protocol/core/test/hub/interactions/publishing-comments.spec.ts @@ -0,0 +1,781 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { + cancelWithPermitForAll, + commentReturningTokenId, + getCommentWithSigParts, +} from '../../helpers/utils'; +import { + abiCoder, + freeCollectModule, + FIRST_PROFILE_ID, + governance, + lensHub, + makeSuiteCleanRoom, + mockReferenceModule, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + OTHER_MOCK_URI, + testWallet, + timedFeeCollectModule, + userAddress, + userTwo, + userTwoAddress, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Publishing Comments', function () { + context('Generic', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(timedFeeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistReferenceModule(mockReferenceModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('UserTwo should fail to publish a comment to a profile owned by User', async function () { + await expect( + lensHub.connect(userTwo).comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + collectModule: ZERO_ADDRESS, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER_OR_DISPATCHER); + }); + + it('User should fail to comment with an unwhitelisted collect module', async function () { + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + collectModule: ZERO_ADDRESS, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.COLLECT_MODULE_NOT_WHITELISTED); + }); + + it('User should fail to comment with an unwhitelisted reference module', async function () { + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: userAddress, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.REFERENCE_MODULE_NOT_WHITELISTED); + }); + + it('User should fail to comment with invalid collect module data format', async function () { + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + collectModule: timedFeeCollectModule.address, + collectModuleInitData: [0x2, 0x12, 0x20], + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.NO_REASON_ABI_DECODE); + }); + + it('User should fail to comment with invalid reference module data format', async function () { + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: mockReferenceModule.address, + referenceModuleInitData: [0x12, 0x23], + }) + ).to.be.revertedWith(ERRORS.NO_REASON_ABI_DECODE); + }); + + it('User should fail to comment on a publication that does not exist', async function () { + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 3, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PUBLICATION_DOES_NOT_EXIST); + }); + + it('User should fail to comment on the same comment they are creating (pubId = 2, commentCeption)', async function () { + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 2, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.CANNOT_COMMENT_ON_SELF); + }); + }); + + context('Scenarios', function () { + it('User should create a comment with empty collect module data, reference module, and reference module data, fetched comment data should be accurate', async function () { + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const pub = await lensHub.getPub(FIRST_PROFILE_ID, 2); + expect(pub.profileIdPointed).to.eq(FIRST_PROFILE_ID); + expect(pub.pubIdPointed).to.eq(1); + expect(pub.contentURI).to.eq(MOCK_URI); + expect(pub.collectModule).to.eq(freeCollectModule.address); + expect(pub.collectNFT).to.eq(ZERO_ADDRESS); + expect(pub.referenceModule).to.eq(ZERO_ADDRESS); + }); + + it('Should return the expected token IDs when commenting publications', async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: 'testwallet', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(testWallet).createProfile({ + to: userTwoAddress, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID + 1, + OTHER_MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + expect( + await commentReturningTokenId({ + vars: { + profileId: FIRST_PROFILE_ID + 1, + contentURI: OTHER_MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }, + }) + ).to.eq(1); + + expect( + await commentReturningTokenId({ + sender: userTwo, + vars: { + profileId: FIRST_PROFILE_ID + 2, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + }, + }) + ).to.eq(1); + + expect( + await commentReturningTokenId({ + sender: testWallet, + vars: { + profileId: FIRST_PROFILE_ID + 1, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + }, + }) + ).to.eq(2); + + expect( + await commentReturningTokenId({ + vars: { + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + }, + }) + ).to.eq(2); + }); + + it('User should create a post using the mock reference module as reference module, then comment on that post', async function () { + const data = abiCoder.encode(['uint256'], ['1']); + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: mockReferenceModule.address, + referenceModuleInitData: data, + }) + ).to.not.be.reverted; + + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 2, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + }); + }); + + context('Meta-tx', function () { + beforeEach(async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('Testwallet should fail to comment with sig with signature deadline mismatch', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + '0' + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: ZERO_ADDRESS, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('Testwallet should fail to comment with sig with invalid deadline', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = []; + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + '0' + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: ZERO_ADDRESS, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: '0', + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('Testwallet should fail to comment with sig with invalid nonce', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = []; + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce + 1, + MAX_UINT256 + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: ZERO_ADDRESS, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('Testwallet should fail to comment with sig with unwhitelisted collect module', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = []; + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + userAddress, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: userAddress, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.COLLECT_MODULE_NOT_WHITELISTED); + }); + + it('TestWallet should fail to comment with sig with unwhitelisted reference module', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + freeCollectModule.address, + collectModuleInitData, + mockReferenceModule.address, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: mockReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.REFERENCE_MODULE_NOT_WHITELISTED); + }); + + it('TestWallet should fail to comment with sig on a publication that does not exist', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + OTHER_MOCK_URI, + FIRST_PROFILE_ID, + '3', + referenceModuleData, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: OTHER_MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '3', + referenceModuleData: referenceModuleData, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PUBLICATION_DOES_NOT_EXIST); + }); + + it('TestWallet should fail to comment with sig on the comment they are creating (commentCeption)', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = []; + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + OTHER_MOCK_URI, + FIRST_PROFILE_ID, + '2', + referenceModuleData, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: OTHER_MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '2', + referenceModuleData: referenceModuleData, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.CANNOT_COMMENT_ON_SELF); + }); + + it('TestWallet should sign attempt to comment with sig, cancel via empty permitForAll, then fail to comment with sig', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + OTHER_MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await cancelWithPermitForAll(); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: OTHER_MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + it('TestWallet should comment with sig, fetched comment data should be accurate', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getCommentWithSigParts( + FIRST_PROFILE_ID, + OTHER_MOCK_URI, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.commentWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: OTHER_MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: referenceModuleData, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const pub = await lensHub.getPub(FIRST_PROFILE_ID, 2); + expect(pub.profileIdPointed).to.eq(FIRST_PROFILE_ID); + expect(pub.pubIdPointed).to.eq(1); + expect(pub.contentURI).to.eq(OTHER_MOCK_URI); + expect(pub.collectModule).to.eq(freeCollectModule.address); + expect(pub.collectNFT).to.eq(ZERO_ADDRESS); + expect(pub.referenceModule).to.eq(ZERO_ADDRESS); + }); + }); + }); +}); diff --git a/lens-protocol/core/test/hub/interactions/publishing-mirrors.spec.ts b/lens-protocol/core/test/hub/interactions/publishing-mirrors.spec.ts new file mode 100644 index 0000000..294a778 --- /dev/null +++ b/lens-protocol/core/test/hub/interactions/publishing-mirrors.spec.ts @@ -0,0 +1,626 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { + cancelWithPermitForAll, + getMirrorWithSigParts, + mirrorReturningTokenId, +} from '../../helpers/utils'; +import { + abiCoder, + freeCollectModule, + FIRST_PROFILE_ID, + governance, + lensHub, + makeSuiteCleanRoom, + mockReferenceModule, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + testWallet, + userAddress, + userTwo, + userTwoAddress, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Publishing mirrors', function () { + context('Generic', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistReferenceModule(mockReferenceModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('UserTwo should fail to publish a mirror to a profile owned by User', async function () { + await expect( + lensHub.connect(userTwo).mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER_OR_DISPATCHER); + }); + + it('User should fail to mirror with an unwhitelisted reference module', async function () { + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: userAddress, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.REFERENCE_MODULE_NOT_WHITELISTED); + }); + + it('User should fail to mirror with invalid reference module data format', async function () { + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: mockReferenceModule.address, + referenceModuleInitData: [0x12, 0x23], + }) + ).to.be.revertedWith(ERRORS.NO_REASON_ABI_DECODE); + }); + + it('User should fail to mirror a publication that does not exist', async function () { + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 2, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PUBLICATION_DOES_NOT_EXIST); + }); + }); + + context('Scenarios', function () { + it('Should return the expected token IDs when mirroring publications', async function () { + await expect( + lensHub.createProfile({ + to: testWallet.address, + handle: 'testwallet', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.createProfile({ + to: userTwoAddress, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + expect( + await mirrorReturningTokenId({ + vars: { + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }, + }) + ).to.eq(2); + + expect( + await mirrorReturningTokenId({ + sender: userTwo, + vars: { + profileId: FIRST_PROFILE_ID + 2, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 2, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }, + }) + ).to.eq(1); + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID + 1, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + expect( + await mirrorReturningTokenId({ + vars: { + profileId: FIRST_PROFILE_ID + 1, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }, + }) + ).to.eq(1); + + expect( + await mirrorReturningTokenId({ + vars: { + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID + 1, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }, + }) + ).to.eq(3); + }); + + it('User should create a mirror with empty reference module and reference module data, fetched mirror data should be accurate', async function () { + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const pub = await lensHub.getPub(FIRST_PROFILE_ID, 2); + expect(pub.profileIdPointed).to.eq(FIRST_PROFILE_ID); + expect(pub.pubIdPointed).to.eq(1); + expect(pub.contentURI).to.eq(''); + expect(pub.collectModule).to.eq(ZERO_ADDRESS); + expect(pub.collectNFT).to.eq(ZERO_ADDRESS); + expect(pub.referenceModule).to.eq(ZERO_ADDRESS); + }); + + it('User should mirror a mirror with empty reference module and reference module data, fetched mirror data should be accurate and point to the original post', async function () { + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 2, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const pub = await lensHub.getPub(FIRST_PROFILE_ID, 3); + expect(pub.profileIdPointed).to.eq(FIRST_PROFILE_ID); + expect(pub.pubIdPointed).to.eq(1); + expect(pub.contentURI).to.eq(''); + expect(pub.collectModule).to.eq(ZERO_ADDRESS); + expect(pub.collectNFT).to.eq(ZERO_ADDRESS); + expect(pub.referenceModule).to.eq(ZERO_ADDRESS); + }); + + it('User should create a post using the mock reference module as reference module, then mirror that post', async function () { + const data = abiCoder.encode(['uint256'], ['1']); + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: mockReferenceModule.address, + referenceModuleInitData: data, + }) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 2, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + }); + }); + + context('Meta-tx', function () { + beforeEach(async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(testWallet).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('Testwallet should fail to mirror with sig with signature deadline mismatch', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + '0' + ); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('Testwallet should fail to mirror with sig with invalid deadline', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + '0' + ); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: '0', + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('Testwallet should fail to mirror with sig with invalid deadline', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce + 1, + MAX_UINT256 + ); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('Testwallet should fail to mirror with sig with unwhitelisted reference module', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + userAddress, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: userAddress, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.REFERENCE_MODULE_NOT_WHITELISTED); + }); + + it('TestWallet should fail to mirror a publication with sig that does not exist yet', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '2', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '2', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.PUBLICATION_DOES_NOT_EXIST); + }); + + it('TestWallet should sign attempt to mirror with sig, cancel via empty permitForAll, then fail to mirror with sig', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await cancelWithPermitForAll(); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + it('Testwallet should mirror with sig, fetched mirror data should be accurate', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '1', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '1', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const pub = await lensHub.getPub(FIRST_PROFILE_ID, 2); + expect(pub.profileIdPointed).to.eq(FIRST_PROFILE_ID); + expect(pub.pubIdPointed).to.eq(1); + expect(pub.contentURI).to.eq(''); + expect(pub.collectModule).to.eq(ZERO_ADDRESS); + expect(pub.collectNFT).to.eq(ZERO_ADDRESS); + expect(pub.referenceModule).to.eq(ZERO_ADDRESS); + }); + + it('TestWallet should mirror a mirror with sig, fetched mirror data should be accurate', async function () { + await expect( + lensHub.connect(testWallet).mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const referenceModuleInitData = []; + const referenceModuleData = []; + + const { v, r, s } = await getMirrorWithSigParts( + FIRST_PROFILE_ID, + FIRST_PROFILE_ID, + '2', + referenceModuleData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.mirrorWithSig({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: '2', + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const pub = await lensHub.getPub(FIRST_PROFILE_ID, 3); + expect(pub.profileIdPointed).to.eq(FIRST_PROFILE_ID); + expect(pub.pubIdPointed).to.eq(1); + expect(pub.contentURI).to.eq(''); + expect(pub.collectModule).to.eq(ZERO_ADDRESS); + expect(pub.collectNFT).to.eq(ZERO_ADDRESS); + expect(pub.referenceModule).to.eq(ZERO_ADDRESS); + }); + }); + }); +}); diff --git a/lens-protocol/core/test/hub/interactions/publishing-posts.spec.ts b/lens-protocol/core/test/hub/interactions/publishing-posts.spec.ts new file mode 100644 index 0000000..bdb748a --- /dev/null +++ b/lens-protocol/core/test/hub/interactions/publishing-posts.spec.ts @@ -0,0 +1,566 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { + cancelWithPermitForAll, + getPostWithSigParts, + postReturningTokenId, +} from '../../helpers/utils'; +import { + freeCollectModule, + FIRST_PROFILE_ID, + governance, + lensHub, + makeSuiteCleanRoom, + mockModuleData, + mockReferenceModule, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + testWallet, + timedFeeCollectModule, + userAddress, + userTwo, + abiCoder, + userTwoAddress, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Publishing Posts', function () { + context('Generic', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('UserTwo should fail to post to a profile owned by User', async function () { + await expect( + lensHub.connect(userTwo).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER_OR_DISPATCHER); + }); + + it('User should fail to post with an unwhitelisted collect module', async function () { + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.COLLECT_MODULE_NOT_WHITELISTED); + }); + + it('User should fail to post with an unwhitelisted reference module', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: userAddress, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.REFERENCE_MODULE_NOT_WHITELISTED); + }); + + it('User should fail to post with invalid collect module data format', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(timedFeeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: timedFeeCollectModule.address, + collectModuleInitData: [0x12, 0x34], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.NO_REASON_ABI_DECODE); + }); + + it('User should fail to post with invalid reference module data format', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistReferenceModule(mockReferenceModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: mockReferenceModule.address, + referenceModuleInitData: [0x12, 0x23], + }) + ).to.be.revertedWith(ERRORS.NO_REASON_ABI_DECODE); + }); + }); + + context('Scenarios', function () { + it('Should return the expected token IDs when mirroring publications', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: testWallet.address, + handle: 'testwallet', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.createProfile({ + to: userTwoAddress, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + expect( + await postReturningTokenId({ + vars: { + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }, + }) + ).to.eq(1); + + expect( + await postReturningTokenId({ + sender: userTwo, + vars: { + profileId: FIRST_PROFILE_ID + 2, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }, + }) + ).to.eq(1); + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID + 1, + MOCK_URI, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + expect( + await postReturningTokenId({ + vars: { + profileId: FIRST_PROFILE_ID + 1, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }, + }) + ).to.eq(1); + + expect( + await postReturningTokenId({ + vars: { + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }, + }) + ).to.eq(2); + }); + + it('User should create a post with empty collect and reference module data, fetched post data should be accurate', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const pub = await lensHub.getPub(FIRST_PROFILE_ID, 1); + expect(pub.profileIdPointed).to.eq(0); + expect(pub.pubIdPointed).to.eq(0); + expect(pub.contentURI).to.eq(MOCK_URI); + expect(pub.collectModule).to.eq(freeCollectModule.address); + expect(pub.collectNFT).to.eq(ZERO_ADDRESS); + expect(pub.referenceModule).to.eq(ZERO_ADDRESS); + }); + + it('User should create a post with a whitelisted collect and reference module', async function () { + await expect( + lensHub.connect(governance).whitelistReferenceModule(mockReferenceModule.address, true) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: mockReferenceModule.address, + referenceModuleInitData: mockModuleData, + }) + ).to.not.be.reverted; + }); + }); + }); + + context('Meta-tx', function () { + beforeEach(async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('Testwallet should fail to post with sig with signature deadline mismatch', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = []; + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + ZERO_ADDRESS, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + '0' + ); + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: ZERO_ADDRESS, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('Testwallet should fail to post with sig with invalid deadline', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = []; + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + ZERO_ADDRESS, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + '0' + ); + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: ZERO_ADDRESS, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: '0', + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('Testwallet should fail to post with sig with invalid nonce', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = []; + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + ZERO_ADDRESS, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce + 1, + MAX_UINT256 + ); + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: ZERO_ADDRESS, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('Testwallet should fail to post with sig with an unwhitelisted collect module', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = []; + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + userAddress, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: userAddress, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.COLLECT_MODULE_NOT_WHITELISTED); + }); + + it('Testwallet should fail to post with sig with an unwhitelisted reference module', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + freeCollectModule.address, + collectModuleInitData, + userAddress, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: userAddress, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.REFERENCE_MODULE_NOT_WHITELISTED); + }); + + it('TestWallet should sign attempt to post with sig, cancel via empty permitForAll, then fail to post with sig', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await cancelWithPermitForAll(); + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + it('TestWallet should post with sig, fetched post data should be accurate', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const collectModuleInitData = abiCoder.encode(['bool'], [true]); + const referenceModuleInitData = []; + const referenceModuleData = []; + const { v, r, s } = await getPostWithSigParts( + FIRST_PROFILE_ID, + MOCK_URI, + freeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + referenceModuleInitData, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.postWithSig({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: referenceModuleInitData, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const pub = await lensHub.getPub(FIRST_PROFILE_ID, 1); + expect(pub.profileIdPointed).to.eq(0); + expect(pub.pubIdPointed).to.eq(0); + expect(pub.contentURI).to.eq(MOCK_URI); + expect(pub.collectModule).to.eq(freeCollectModule.address); + expect(pub.collectNFT).to.eq(ZERO_ADDRESS); + expect(pub.referenceModule).to.eq(ZERO_ADDRESS); + }); + }); + }); +}); diff --git a/lens-protocol/core/test/hub/profiles/default-profile.spec.ts b/lens-protocol/core/test/hub/profiles/default-profile.spec.ts new file mode 100644 index 0000000..317c565 --- /dev/null +++ b/lens-protocol/core/test/hub/profiles/default-profile.spec.ts @@ -0,0 +1,356 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { cancelWithPermitForAll, getSetDefaultProfileWithSigParts } from '../../helpers/utils'; +import { + FIRST_PROFILE_ID, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + testWallet, + userAddress, + userTwo, + userTwoAddress, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Default profile Functionality', function () { + context('Generic', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('UserTwo should fail to set the default profile as a profile owned by user 1', async function () { + await expect( + lensHub.connect(userTwo).setDefaultProfile(FIRST_PROFILE_ID) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER); + }); + }); + + context('Scenarios', function () { + it('User should set the default profile', async function () { + await expect(lensHub.setDefaultProfile(FIRST_PROFILE_ID)).to.not.be.reverted; + expect(await lensHub.defaultProfile(userAddress)).to.eq(FIRST_PROFILE_ID); + }); + + it('User should set the default profile and then be able to unset it', async function () { + await expect(lensHub.setDefaultProfile(FIRST_PROFILE_ID)).to.not.be.reverted; + expect(await lensHub.defaultProfile(userAddress)).to.eq(FIRST_PROFILE_ID); + + await expect(lensHub.setDefaultProfile(0)).to.not.be.reverted; + expect(await lensHub.defaultProfile(userAddress)).to.eq(0); + }); + + it('User should set the default profile and then be able to change it to another', async function () { + await expect(lensHub.setDefaultProfile(FIRST_PROFILE_ID)).to.not.be.reverted; + expect(await lensHub.defaultProfile(userAddress)).to.eq(FIRST_PROFILE_ID); + + await expect( + lensHub.createProfile({ + to: userAddress, + handle: new Date().getTime().toString(), + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(lensHub.setDefaultProfile(2)).to.not.be.reverted; + expect(await lensHub.defaultProfile(userAddress)).to.eq(2); + }); + + it('User should set the default profile and then transfer it, their default profile should be unset', async function () { + await expect(lensHub.setDefaultProfile(FIRST_PROFILE_ID)).to.not.be.reverted; + expect(await lensHub.defaultProfile(userAddress)).to.eq(FIRST_PROFILE_ID); + + await expect( + lensHub.transferFrom(userAddress, userTwoAddress, FIRST_PROFILE_ID) + ).to.not.be.reverted; + expect(await lensHub.defaultProfile(userAddress)).to.eq(0); + }); + }); + }); + + context('Meta-tx', function () { + beforeEach(async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('TestWallet should fail to set default profile with sig with signature deadline mismatch', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDefaultProfileWithSigParts( + testWallet.address, + FIRST_PROFILE_ID, + nonce, + '0' + ); + + await expect( + lensHub.setDefaultProfileWithSig({ + profileId: FIRST_PROFILE_ID, + wallet: testWallet.address, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should fail to set default profile with sig with invalid deadline', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDefaultProfileWithSigParts( + testWallet.address, + FIRST_PROFILE_ID, + nonce, + '0' + ); + + await expect( + lensHub.setDefaultProfileWithSig({ + profileId: FIRST_PROFILE_ID, + wallet: testWallet.address, + sig: { + v, + r, + s, + deadline: '0', + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('TestWallet should fail to set default profile with sig with invalid nonce', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDefaultProfileWithSigParts( + testWallet.address, + FIRST_PROFILE_ID, + nonce + 1, + MAX_UINT256 + ); + + await expect( + lensHub.setDefaultProfileWithSig({ + profileId: FIRST_PROFILE_ID, + wallet: testWallet.address, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should sign attempt to set default profile with sig, cancel with empty permitForAll, then fail to set default profile with sig', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDefaultProfileWithSigParts( + testWallet.address, + FIRST_PROFILE_ID, + nonce, + MAX_UINT256 + ); + + await cancelWithPermitForAll(); + + await expect( + lensHub.setDefaultProfileWithSig({ + profileId: FIRST_PROFILE_ID, + wallet: testWallet.address, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + it('TestWallet should set the default profile with sig', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDefaultProfileWithSigParts( + testWallet.address, + FIRST_PROFILE_ID, + nonce, + MAX_UINT256 + ); + + const defaultProfileBeforeUse = await lensHub.defaultProfile(testWallet.address); + + await expect( + lensHub.setDefaultProfileWithSig({ + profileId: FIRST_PROFILE_ID, + wallet: testWallet.address, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const defaultProfileAfter = await lensHub.defaultProfile(testWallet.address); + + expect(defaultProfileBeforeUse).to.eq(0); + expect(defaultProfileAfter).to.eq(FIRST_PROFILE_ID); + }); + + it('TestWallet should set the default profile with sig and then be able to unset it', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDefaultProfileWithSigParts( + testWallet.address, + FIRST_PROFILE_ID, + nonce, + MAX_UINT256 + ); + + const defaultProfileBeforeUse = await lensHub.defaultProfile(testWallet.address); + + await expect( + lensHub.setDefaultProfileWithSig({ + wallet: testWallet.address, + profileId: FIRST_PROFILE_ID, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const defaultProfileAfter = await lensHub.defaultProfile(testWallet.address); + + expect(defaultProfileBeforeUse).to.eq(0); + expect(defaultProfileAfter).to.eq(FIRST_PROFILE_ID); + + const nonce2 = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const signature2 = await getSetDefaultProfileWithSigParts( + testWallet.address, + 0, + nonce2, + MAX_UINT256 + ); + + const defaultProfileBeforeUse2 = await lensHub.defaultProfile(testWallet.address); + + await expect( + lensHub.setDefaultProfileWithSig({ + wallet: testWallet.address, + profileId: 0, + sig: { + v: signature2.v, + r: signature2.r, + s: signature2.s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const defaultProfileAfter2 = await lensHub.defaultProfile(testWallet.address); + + expect(defaultProfileBeforeUse2).to.eq(FIRST_PROFILE_ID); + expect(defaultProfileAfter2).to.eq(0); + }); + + it('TestWallet should set the default profile and then be able to change it to another', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDefaultProfileWithSigParts( + testWallet.address, + FIRST_PROFILE_ID, + nonce, + MAX_UINT256 + ); + + const defaultProfileBeforeUse = await lensHub.defaultProfile(testWallet.address); + + await expect( + lensHub.setDefaultProfileWithSig({ + profileId: FIRST_PROFILE_ID, + wallet: testWallet.address, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const defaultProfileAfter = await lensHub.defaultProfile(testWallet.address); + + expect(defaultProfileBeforeUse).to.eq(0); + expect(defaultProfileAfter).to.eq(FIRST_PROFILE_ID); + + await expect( + lensHub.createProfile({ + to: testWallet.address, + handle: new Date().getTime().toString(), + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + const nonce2 = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const signature2 = await getSetDefaultProfileWithSigParts( + testWallet.address, + FIRST_PROFILE_ID + 1, + nonce2, + MAX_UINT256 + ); + + const defaultProfileBeforeUse2 = await lensHub.defaultProfile(testWallet.address); + + await expect( + lensHub.setDefaultProfileWithSig({ + profileId: 2, + wallet: testWallet.address, + sig: { + v: signature2.v, + r: signature2.r, + s: signature2.s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + const defaultProfileAfter2 = await lensHub.defaultProfile(testWallet.address); + + expect(defaultProfileBeforeUse2).to.eq(1); + expect(defaultProfileAfter2).to.eq(2); + }); + }); + }); +}); diff --git a/lens-protocol/core/test/hub/profiles/dispatcher.spec.ts b/lens-protocol/core/test/hub/profiles/dispatcher.spec.ts new file mode 100644 index 0000000..f8f669b --- /dev/null +++ b/lens-protocol/core/test/hub/profiles/dispatcher.spec.ts @@ -0,0 +1,286 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { cancelWithPermitForAll, getSetDispatcherWithSigParts } from '../../helpers/utils'; +import { + freeCollectModule, + FIRST_PROFILE_ID, + governance, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + testWallet, + userAddress, + userTwo, + userTwoAddress, + abiCoder, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Dispatcher Functionality', function () { + context('Generic', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('UserTwo should fail to set dispatcher on profile owned by user 1', async function () { + await expect( + lensHub.connect(userTwo).setDispatcher(FIRST_PROFILE_ID, userTwoAddress) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER); + }); + + it('UserTwo should fail to publish on profile owned by user 1 without being a dispatcher', async function () { + await expect( + lensHub.connect(userTwo).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER_OR_DISPATCHER); + }); + + it("User should set userTwo as dispatcher, userTwo should fail to set follow module on user's profile", async function () { + await expect(lensHub.setDispatcher(FIRST_PROFILE_ID, userTwoAddress)).to.not.be.reverted; + await expect( + lensHub.connect(userTwo).setFollowModule(FIRST_PROFILE_ID, ZERO_ADDRESS, []) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER); + }); + }); + + context('Scenarios', function () { + it('User should set user two as a dispatcher on their profile, user two should post, comment and mirror', async function () { + await expect(lensHub.setDispatcher(FIRST_PROFILE_ID, userTwoAddress)).to.not.be.reverted; + + await expect( + lensHub.connect(userTwo).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(userTwo).comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(userTwo).mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + }); + }); + + context('Meta-tx', function () { + beforeEach(async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('TestWallet should fail to set dispatcher with sig with signature deadline mismatch', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDispatcherWithSigParts( + FIRST_PROFILE_ID, + userTwoAddress, + nonce, + '0' + ); + + await expect( + lensHub.setDispatcherWithSig({ + profileId: FIRST_PROFILE_ID, + dispatcher: userTwoAddress, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should fail to set dispatcher with sig with invalid deadline', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDispatcherWithSigParts( + FIRST_PROFILE_ID, + userTwoAddress, + nonce, + '0' + ); + + await expect( + lensHub.setDispatcherWithSig({ + profileId: FIRST_PROFILE_ID, + dispatcher: userTwoAddress, + sig: { + v, + r, + s, + deadline: '0', + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('TestWallet should fail to set dispatcher with sig with invalid nonce', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDispatcherWithSigParts( + FIRST_PROFILE_ID, + userTwoAddress, + nonce + 1, + MAX_UINT256 + ); + + await expect( + lensHub.setDispatcherWithSig({ + profileId: FIRST_PROFILE_ID, + dispatcher: userTwoAddress, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should sign attempt to set dispatcher with sig, cancel via empty permitForAll, fail to set dispatcher with sig', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDispatcherWithSigParts( + FIRST_PROFILE_ID, + userTwoAddress, + nonce, + MAX_UINT256 + ); + + await cancelWithPermitForAll(); + + await expect( + lensHub.setDispatcherWithSig({ + profileId: FIRST_PROFILE_ID, + dispatcher: userTwoAddress, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + it('TestWallet should set user two as dispatcher for their profile, user two should post, comment and mirror', async function () { + const nonce = (await lensHub.sigNonces(testWallet.address)).toNumber(); + const { v, r, s } = await getSetDispatcherWithSigParts( + FIRST_PROFILE_ID, + userTwoAddress, + nonce, + MAX_UINT256 + ); + + await expect( + lensHub.setDispatcherWithSig({ + profileId: FIRST_PROFILE_ID, + dispatcher: userTwoAddress, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(userTwo).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(userTwo).comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(userTwo).mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + }); + }); +}); diff --git a/lens-protocol/core/test/hub/profiles/profile-creation.spec.ts b/lens-protocol/core/test/hub/profiles/profile-creation.spec.ts new file mode 100644 index 0000000..96a1b8d --- /dev/null +++ b/lens-protocol/core/test/hub/profiles/profile-creation.spec.ts @@ -0,0 +1,332 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { BigNumber } from 'ethers'; +import { TokenDataStructOutput } from '../../../typechain-types/LensHub'; +import { ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { createProfileReturningTokenId, getTimestamp, waitForTx } from '../../helpers/utils'; +import { + FIRST_PROFILE_ID, + governance, + lensHub, + makeSuiteCleanRoom, + MAX_PROFILE_IMAGE_URI_LENGTH, + mockFollowModule, + mockModuleData, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + userAddress, + userTwo, + userTwoAddress, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Profile Creation', function () { + context('Generic', function () { + context('Negatives', function () { + it('User should fail to create a profile with a handle longer than 31 bytes', async function () { + const val = '11111111111111111111111111111111'; + expect(val.length).to.eq(32); + await expect( + lensHub.createProfile({ + to: userAddress, + handle: val, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.INVALID_HANDLE_LENGTH); + }); + + it('User should fail to create a profile with an empty handle (0 length bytes)', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: '', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.INVALID_HANDLE_LENGTH); + }); + + it('User should fail to create a profile with a handle with a capital letter', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: 'Egg', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_CONTAINS_INVALID_CHARACTERS); + }); + + it('User should fail to create a profile with a handle with an invalid character', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: 'egg?', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_CONTAINS_INVALID_CHARACTERS); + }); + + it('User should fail to create a profile with a unwhitelisted follow module', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: userAddress, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.FOLLOW_MODULE_NOT_WHITELISTED); + }); + + it('User should fail to create a profile with with invalid follow module data format', async function () { + await expect( + lensHub.connect(governance).whitelistFollowModule(mockFollowModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: mockFollowModule.address, + followModuleInitData: [0x12, 0x34], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.NO_REASON_ABI_DECODE); + }); + + it('User should fail to create a profile when they are not a whitelisted profile creator', async function () { + await expect( + lensHub.connect(governance).whitelistProfileCreator(userAddress, false) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.PROFILE_CREATOR_NOT_WHITELISTED); + }); + + it('User should fail to create a profile with invalid image URI length', async function () { + const profileURITooLong = MOCK_PROFILE_URI.repeat(500); + expect(profileURITooLong.length).to.be.greaterThan(MAX_PROFILE_IMAGE_URI_LENGTH); + + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: profileURITooLong, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.INVALID_IMAGE_URI_LENGTH); + }); + }); + + context('Scenarios', function () { + it('User should be able to create a profile with a handle, receive an NFT and the handle should resolve to the NFT ID, userTwo should do the same', async function () { + let timestamp: any; + let owner: string; + let totalSupply: BigNumber; + let profileId: BigNumber; + let mintTimestamp: BigNumber; + let tokenData: TokenDataStructOutput; + + expect( + await createProfileReturningTokenId({ + vars: { + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }, + }) + ).to.eq(FIRST_PROFILE_ID); + + timestamp = await getTimestamp(); + owner = await lensHub.ownerOf(FIRST_PROFILE_ID); + totalSupply = await lensHub.totalSupply(); + profileId = await lensHub.getProfileIdByHandle(MOCK_PROFILE_HANDLE); + mintTimestamp = await lensHub.mintTimestampOf(FIRST_PROFILE_ID); + tokenData = await lensHub.tokenDataOf(FIRST_PROFILE_ID); + expect(owner).to.eq(userAddress); + expect(totalSupply).to.eq(FIRST_PROFILE_ID); + expect(profileId).to.eq(FIRST_PROFILE_ID); + expect(mintTimestamp).to.eq(timestamp); + expect(tokenData.owner).to.eq(userAddress); + expect(tokenData.mintTimestamp).to.eq(timestamp); + + const secondProfileId = FIRST_PROFILE_ID + 1; + const secondProfileHandle = '2nd_profile'; + expect( + await createProfileReturningTokenId({ + sender: userTwo, + vars: { + to: userTwoAddress, + handle: secondProfileHandle, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }, + }) + ).to.eq(secondProfileId); + + timestamp = await getTimestamp(); + owner = await lensHub.ownerOf(secondProfileId); + totalSupply = await lensHub.totalSupply(); + profileId = await lensHub.getProfileIdByHandle(secondProfileHandle); + mintTimestamp = await lensHub.mintTimestampOf(secondProfileId); + tokenData = await lensHub.tokenDataOf(secondProfileId); + expect(owner).to.eq(userTwoAddress); + expect(totalSupply).to.eq(secondProfileId); + expect(profileId).to.eq(secondProfileId); + expect(mintTimestamp).to.eq(timestamp); + expect(tokenData.owner).to.eq(userTwoAddress); + expect(tokenData.mintTimestamp).to.eq(timestamp); + }); + + it('Should return the expected token IDs when creating profiles', async function () { + expect( + await createProfileReturningTokenId({ + vars: { + to: userAddress, + handle: 'token.id_1', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }, + }) + ).to.eq(FIRST_PROFILE_ID); + + const secondProfileId = FIRST_PROFILE_ID + 1; + expect( + await createProfileReturningTokenId({ + sender: userTwo, + vars: { + to: userTwoAddress, + handle: 'token.id_2', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }, + }) + ).to.eq(secondProfileId); + + const thirdProfileId = secondProfileId + 1; + expect( + await createProfileReturningTokenId({ + vars: { + to: userAddress, + handle: 'token.id_3', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }, + }) + ).to.eq(thirdProfileId); + }); + + it('User should be able to create a profile with a handle including "-" and "_" characters', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: 'morse--__-_--code', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + it('User should be able to create a profile with a handle 16 bytes long, then fail to create with the same handle, and create again with a different handle', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: '123456789012345', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.createProfile({ + to: userAddress, + handle: '123456789012345', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.PROFILE_HANDLE_TAKEN); + await expect( + lensHub.createProfile({ + to: userAddress, + handle: 'abcdefghijklmno', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + it('User should be able to create a profile with a whitelisted follow module', async function () { + await expect( + lensHub.connect(governance).whitelistFollowModule(mockFollowModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: mockFollowModule.address, + followModuleInitData: mockModuleData, + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + it('User should create a profile for userTwo', async function () { + await expect( + lensHub.createProfile({ + to: userTwoAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + expect(await lensHub.ownerOf(FIRST_PROFILE_ID)).to.eq(userTwoAddress); + }); + }); + }); +}); diff --git a/lens-protocol/core/test/hub/profiles/profile-uri.spec.ts b/lens-protocol/core/test/hub/profiles/profile-uri.spec.ts new file mode 100644 index 0000000..994c8d9 --- /dev/null +++ b/lens-protocol/core/test/hub/profiles/profile-uri.spec.ts @@ -0,0 +1,530 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { keccak256, toUtf8Bytes } from 'ethers/lib/utils'; +import { FollowNFT__factory } from '../../../typechain-types'; +import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { + cancelWithPermitForAll, + getDecodedSvgImage, + getMetadataFromBase64TokenUri, + getSetFollowNFTURIWithSigParts, + getSetProfileImageURIWithSigParts, + loadTestResourceAsUtf8String, +} from '../../helpers/utils'; +import { + FIRST_PROFILE_ID, + lensHub, + makeSuiteCleanRoom, + MAX_PROFILE_IMAGE_URI_LENGTH, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + OTHER_MOCK_URI, + testWallet, + user, + userAddress, + userTwo, + userTwoAddress, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Profile URI Functionality', function () { + context('Generic', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('UserTwo should fail to set the profile URI on profile owned by user 1', async function () { + await expect( + lensHub.connect(userTwo).setProfileImageURI(FIRST_PROFILE_ID, MOCK_URI) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER_OR_DISPATCHER); + }); + + it('UserTwo should fail to set the profile URI on profile owned by user 1', async function () { + const profileURITooLong = MOCK_URI.repeat(500); + expect(profileURITooLong.length).to.be.greaterThan(MAX_PROFILE_IMAGE_URI_LENGTH); + await expect( + lensHub.setProfileImageURI(FIRST_PROFILE_ID, profileURITooLong) + ).to.be.revertedWith(ERRORS.INVALID_IMAGE_URI_LENGTH); + }); + + it('UserTwo should fail to change the follow NFT URI for profile one', async function () { + await expect( + lensHub.connect(userTwo).setFollowNFTURI(FIRST_PROFILE_ID, OTHER_MOCK_URI) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER_OR_DISPATCHER); + }); + }); + + context('Scenarios', function () { + it('User should have a custom picture tokenURI after setting the profile imageURI', async function () { + await expect(lensHub.setProfileImageURI(FIRST_PROFILE_ID, MOCK_URI)).to.not.be.reverted; + const tokenUri = await lensHub.tokenURI(FIRST_PROFILE_ID); + const metadata = await getMetadataFromBase64TokenUri(tokenUri); + expect(metadata.name).to.eq(`@${MOCK_PROFILE_HANDLE}`); + expect(metadata.description).to.eq(`@${MOCK_PROFILE_HANDLE} - Lens profile`); + const expectedAttributes = [ + { trait_type: 'id', value: `#${FIRST_PROFILE_ID.toString()}` }, + { trait_type: 'followers', value: '0' }, + { trait_type: 'owner', value: userAddress.toLowerCase() }, + { trait_type: 'handle', value: `@${MOCK_PROFILE_HANDLE}` }, + ]; + expect(metadata.attributes).to.eql(expectedAttributes); + const actualSvg = await getDecodedSvgImage(metadata); + const expectedSvg = loadTestResourceAsUtf8String('profile-token-uri-images/mock.svg'); + expect(actualSvg).to.eq(expectedSvg); + }); + + it('Default image should be used when no imageURI set', async function () { + await expect(lensHub.setProfileImageURI(FIRST_PROFILE_ID, '')).to.not.be.reverted; + const tokenUri = await lensHub.tokenURI(FIRST_PROFILE_ID); + const metadata = await getMetadataFromBase64TokenUri(tokenUri); + expect(metadata.name).to.eq(`@${MOCK_PROFILE_HANDLE}`); + expect(metadata.description).to.eq(`@${MOCK_PROFILE_HANDLE} - Lens profile`); + const expectedAttributes = [ + { trait_type: 'id', value: `#${FIRST_PROFILE_ID.toString()}` }, + { trait_type: 'followers', value: '0' }, + { trait_type: 'owner', value: userAddress.toLowerCase() }, + { trait_type: 'handle', value: `@${MOCK_PROFILE_HANDLE}` }, + ]; + expect(metadata.attributes).to.eql(expectedAttributes); + const actualSvg = await getDecodedSvgImage(metadata); + const expectedSvg = loadTestResourceAsUtf8String('profile-token-uri-images/default.svg'); + expect(actualSvg).to.eq(expectedSvg); + }); + + it('Default image should be used when imageURI contains double-quotes', async function () { + const imageUri = + 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrztRLMiMPL8wBuTGsMnR" { + it('Should fail to deploy a LensHub implementation with zero address follow NFT impl', async function () { + await expect( + new LensHub__factory(hubLibs, deployer).deploy(ZERO_ADDRESS, userAddress) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Should fail to deploy a LensHub implementation with zero address collect NFT impl', async function () { + await expect( + new LensHub__factory(hubLibs, deployer).deploy(userAddress, ZERO_ADDRESS) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Should fail to deploy a FollowNFT implementation with zero address hub', async function () { + await expect(new FollowNFT__factory(deployer).deploy(ZERO_ADDRESS)).to.be.revertedWith( + ERRORS.INIT_PARAMS_INVALID + ); + }); + + it('Should fail to deploy a CollectNFT implementation with zero address hub', async function () { + await expect(new CollectNFT__factory(deployer).deploy(ZERO_ADDRESS)).to.be.revertedWith( + ERRORS.INIT_PARAMS_INVALID + ); + }); + + it('Deployer should not be able to initialize implementation due to address(this) check', async function () { + await expect( + lensHubImpl.initialize(LENS_HUB_NFT_NAME, LENS_HUB_NFT_SYMBOL, governanceAddress) + ).to.be.revertedWith(ERRORS.CANNOT_INIT_IMPL); + }); + + it("User should fail to initialize lensHub proxy after it's already been initialized via the proxy constructor", async function () { + // Initialization happens in __setup.spec.ts + await expect( + lensHub.connect(user).initialize('name', 'symbol', userAddress) + ).to.be.revertedWith(ERRORS.INITIALIZED); + }); + + it('Deployer should deploy a LensHub implementation, a proxy, initialize it, and fail to initialize it again', async function () { + const newImpl = await new LensHub__factory(hubLibs, deployer).deploy(userAddress, userAddress); + + let data = newImpl.interface.encodeFunctionData('initialize', [ + LENS_HUB_NFT_NAME, + LENS_HUB_NFT_SYMBOL, + governanceAddress, + ]); + + const proxy = await new TransparentUpgradeableProxy__factory(deployer).deploy( + newImpl.address, + deployerAddress, + data + ); + + await expect( + LensHub__factory.connect(proxy.address, user).initialize('name', 'symbol', userAddress) + ).to.be.revertedWith(ERRORS.INITIALIZED); + }); + + it('User should not be able to call admin-only functions on proxy (should fallback) since deployer is admin', async function () { + const proxy = TransparentUpgradeableProxy__factory.connect(lensHub.address, user); + await expect(proxy.upgradeTo(userAddress)).to.be.revertedWith(ERRORS.NO_SELECTOR); + await expect(proxy.upgradeToAndCall(userAddress, [])).to.be.revertedWith(ERRORS.NO_SELECTOR); + }); + + it('Deployer should be able to call admin-only functions on proxy', async function () { + const proxy = TransparentUpgradeableProxy__factory.connect(lensHub.address, deployer); + const newImpl = await new LensHub__factory(hubLibs, deployer).deploy(userAddress, userAddress); + await expect(proxy.upgradeTo(newImpl.address)).to.not.be.reverted; + }); + + it('Deployer should transfer admin to user, deployer should fail to call admin-only functions, user should call admin-only functions', async function () { + const proxy = TransparentUpgradeableProxy__factory.connect(lensHub.address, deployer); + + await expect(proxy.changeAdmin(userAddress)).to.not.be.reverted; + + await expect(proxy.upgradeTo(userAddress)).to.be.revertedWith(ERRORS.NO_SELECTOR); + await expect(proxy.upgradeToAndCall(userAddress, [])).to.be.revertedWith(ERRORS.NO_SELECTOR); + + const newImpl = await new LensHub__factory(hubLibs, deployer).deploy(userAddress, userAddress); + + await expect(proxy.connect(user).upgradeTo(newImpl.address)).to.not.be.reverted; + }); + + it('Should fail to deploy a fee collect module with zero address hub', async function () { + await expect( + new TimedFeeCollectModule__factory(deployer).deploy(ZERO_ADDRESS, moduleGlobals.address) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Should fail to deploy a fee collect module with zero address module globals', async function () { + await expect( + new TimedFeeCollectModule__factory(deployer).deploy(lensHub.address, ZERO_ADDRESS) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Should fail to deploy a fee follow module with zero address hub', async function () { + await expect( + new FeeFollowModule__factory(deployer).deploy(ZERO_ADDRESS, moduleGlobals.address) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Should fail to deploy a fee follow module with zero address module globals', async function () { + await expect( + new FeeFollowModule__factory(deployer).deploy(lensHub.address, ZERO_ADDRESS) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Should fail to deploy module globals with zero address governance', async function () { + await expect( + new ModuleGlobals__factory(deployer).deploy(ZERO_ADDRESS, treasuryAddress, TREASURY_FEE_BPS) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Should fail to deploy module globals with zero address treasury', async function () { + await expect( + new ModuleGlobals__factory(deployer).deploy(governanceAddress, ZERO_ADDRESS, TREASURY_FEE_BPS) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Should fail to deploy module globals with treausury fee > BPS_MAX / 2', async function () { + await expect( + new ModuleGlobals__factory(deployer).deploy(governanceAddress, treasuryAddress, 5001) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Should fail to deploy a fee module with treasury fee equal to or higher than maximum BPS', async function () { + await expect( + new ModuleGlobals__factory(deployer).deploy(ZERO_ADDRESS, treasuryAddress, BPS_MAX) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + + await expect( + new ModuleGlobals__factory(deployer).deploy(ZERO_ADDRESS, treasuryAddress, BPS_MAX + 1) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Validates LensHub name & symbol', async function () { + const name = LENS_HUB_NFT_NAME; + const symbol = await lensHub.symbol(); + + expect(name).to.eq(LENS_HUB_NFT_NAME); + expect(symbol).to.eq(LENS_HUB_NFT_SYMBOL); + }); +}); diff --git a/lens-protocol/core/test/other/events.spec.ts b/lens-protocol/core/test/other/events.spec.ts new file mode 100644 index 0000000..9860392 --- /dev/null +++ b/lens-protocol/core/test/other/events.spec.ts @@ -0,0 +1,690 @@ +import { TransactionReceipt } from '@ethersproject/providers'; +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { TransparentUpgradeableProxy__factory } from '../../typechain-types'; +import { MAX_UINT256, ZERO_ADDRESS } from '../helpers/constants'; +import { + getAbbreviation, + getTimestamp, + matchEvent, + ProtocolState, + waitForTx, +} from '../helpers/utils'; +import { + approvalFollowModule, + deployer, + deployerAddress, + freeCollectModule, + FIRST_PROFILE_ID, + governance, + governanceAddress, + lensHub, + lensHubImpl, + LENS_HUB_NFT_NAME, + LENS_HUB_NFT_SYMBOL, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + moduleGlobals, + treasuryAddress, + TREASURY_FEE_BPS, + user, + userAddress, + userTwo, + userTwoAddress, + abiCoder, + feeCollectModule, + currency, +} from '../__setup.spec'; + +/** + * Note: We use the `lensHubImpl` contract to test ERC721 specific events. + * + * TODO: Add specific test cases to ensure all module encoded return data parameters are + * as expected. + * + * TODO: Add module deployment tests. + */ +makeSuiteCleanRoom('Events', function () { + let receipt: TransactionReceipt; + + context('Misc', function () { + it('Proxy initialization should emit expected events', async function () { + let data = lensHubImpl.interface.encodeFunctionData('initialize', [ + LENS_HUB_NFT_NAME, + LENS_HUB_NFT_SYMBOL, + governanceAddress, + ]); + + let proxy = await new TransparentUpgradeableProxy__factory(deployer).deploy( + lensHubImpl.address, + deployerAddress, + data + ); + + receipt = await waitForTx(proxy.deployTransaction, true); + + expect(receipt.logs.length).to.eq(5); + matchEvent(receipt, 'Upgraded', [lensHubImpl.address], proxy); + matchEvent(receipt, 'AdminChanged', [ZERO_ADDRESS, deployerAddress], proxy); + matchEvent(receipt, 'GovernanceSet', [ + deployerAddress, + ZERO_ADDRESS, + governanceAddress, + await getTimestamp(), + ]); + matchEvent(receipt, 'StateSet', [ + deployerAddress, + ProtocolState.Unpaused, + ProtocolState.Paused, + await getTimestamp(), + ]); + matchEvent(receipt, 'BaseInitialized', [ + LENS_HUB_NFT_NAME, + LENS_HUB_NFT_SYMBOL, + await getTimestamp(), + ]); + }); + }); + + context('Hub Governance', function () { + it('Governance change should emit expected event', async function () { + receipt = await waitForTx(lensHub.connect(governance).setGovernance(userAddress)); + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'GovernanceSet', [ + governanceAddress, + governanceAddress, + userAddress, + await getTimestamp(), + ]); + }); + + it('Emergency admin change should emit expected event', async function () { + receipt = await waitForTx(lensHub.connect(governance).setEmergencyAdmin(userAddress)); + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'EmergencyAdminSet', [ + governanceAddress, + ZERO_ADDRESS, + userAddress, + await getTimestamp(), + ]); + }); + + it('Protocol state change by governance should emit expected event', async function () { + receipt = await waitForTx(lensHub.connect(governance).setState(ProtocolState.Paused)); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'StateSet', [ + governanceAddress, + ProtocolState.Unpaused, + ProtocolState.Paused, + await getTimestamp(), + ]); + + receipt = await waitForTx( + lensHub.connect(governance).setState(ProtocolState.PublishingPaused) + ); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'StateSet', [ + governanceAddress, + ProtocolState.Paused, + ProtocolState.PublishingPaused, + await getTimestamp(), + ]); + + receipt = await waitForTx(lensHub.connect(governance).setState(ProtocolState.Unpaused)); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'StateSet', [ + governanceAddress, + ProtocolState.PublishingPaused, + ProtocolState.Unpaused, + await getTimestamp(), + ]); + }); + + it('Protocol state change by emergency admin should emit expected events', async function () { + await waitForTx(lensHub.connect(governance).setEmergencyAdmin(userAddress)); + + receipt = await waitForTx(lensHub.connect(user).setState(ProtocolState.PublishingPaused)); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'StateSet', [ + userAddress, + ProtocolState.Unpaused, + ProtocolState.PublishingPaused, + await getTimestamp(), + ]); + + receipt = await waitForTx(lensHub.connect(user).setState(ProtocolState.Paused)); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'StateSet', [ + userAddress, + ProtocolState.PublishingPaused, + ProtocolState.Paused, + await getTimestamp(), + ]); + }); + + it('Follow module whitelisting functions should emit expected event', async function () { + receipt = await waitForTx( + lensHub.connect(governance).whitelistFollowModule(userAddress, true) + ); + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'FollowModuleWhitelisted', [userAddress, true, await getTimestamp()]); + + receipt = await waitForTx( + lensHub.connect(governance).whitelistFollowModule(userAddress, false) + ); + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'FollowModuleWhitelisted', [userAddress, false, await getTimestamp()]); + }); + + it('Reference module whitelisting functions should emit expected event', async function () { + receipt = await waitForTx( + lensHub.connect(governance).whitelistReferenceModule(userAddress, true) + ); + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'ReferenceModuleWhitelisted', [userAddress, true, await getTimestamp()]); + + receipt = await waitForTx( + lensHub.connect(governance).whitelistReferenceModule(userAddress, false) + ); + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'ReferenceModuleWhitelisted', [userAddress, false, await getTimestamp()]); + }); + + it('Collect module whitelisting functions should emit expected event', async function () { + receipt = await waitForTx( + lensHub.connect(governance).whitelistCollectModule(userAddress, true) + ); + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'CollectModuleWhitelisted', [userAddress, true, await getTimestamp()]); + + receipt = await waitForTx( + lensHub.connect(governance).whitelistCollectModule(userAddress, false) + ); + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'CollectModuleWhitelisted', [userAddress, false, await getTimestamp()]); + }); + }); + + context('Hub Interaction', function () { + async function createProfile() { + await waitForTx( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ); + } + + it('Profile creation for other user should emit the correct events', async function () { + receipt = await waitForTx( + lensHub.createProfile({ + to: userTwoAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ); + + expect(receipt.logs.length).to.eq(2); + matchEvent( + receipt, + 'Transfer', + [ZERO_ADDRESS, userTwoAddress, FIRST_PROFILE_ID], + lensHubImpl + ); + matchEvent(receipt, 'ProfileCreated', [ + FIRST_PROFILE_ID, + userAddress, + userTwoAddress, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + ZERO_ADDRESS, + [], + MOCK_FOLLOW_NFT_URI, + await getTimestamp(), + ]); + }); + + it('Profile creation should emit the correct events', async function () { + receipt = await waitForTx( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ); + + expect(receipt.logs.length).to.eq(2); + matchEvent(receipt, 'Transfer', [ZERO_ADDRESS, userAddress, FIRST_PROFILE_ID], lensHubImpl); + matchEvent(receipt, 'ProfileCreated', [ + FIRST_PROFILE_ID, + userAddress, + userAddress, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + ZERO_ADDRESS, + [], + MOCK_FOLLOW_NFT_URI, + await getTimestamp(), + ]); + }); + + it('Setting follow module should emit correct events', async function () { + await createProfile(); + + await waitForTx( + lensHub.connect(governance).whitelistFollowModule(approvalFollowModule.address, true) + ); + + receipt = await waitForTx( + lensHub.setFollowModule(FIRST_PROFILE_ID, approvalFollowModule.address, []) + ); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'FollowModuleSet', [ + FIRST_PROFILE_ID, + approvalFollowModule.address, + [], + await getTimestamp(), + ]); + }); + + it('Setting dispatcher should emit correct events', async function () { + await createProfile(); + + receipt = await waitForTx(lensHub.setDispatcher(FIRST_PROFILE_ID, userAddress)); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'DispatcherSet', [FIRST_PROFILE_ID, userAddress, await getTimestamp()]); + }); + + it('Posting should emit the correct events', async function () { + await createProfile(); + + await waitForTx( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ); + + receipt = await waitForTx( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'PostCreated', [ + FIRST_PROFILE_ID, + 1, + MOCK_URI, + freeCollectModule.address, + abiCoder.encode(['bool'], [true]), + ZERO_ADDRESS, + [], + await getTimestamp(), + ]); + }); + + it('Commenting should emit the correct events', async function () { + await createProfile(); + + await waitForTx( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ); + await waitForTx( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ); + + receipt = await waitForTx( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ); + + expect(receipt.logs.length).to.eq(1); + + matchEvent(receipt, 'CommentCreated', [ + FIRST_PROFILE_ID, + 2, + MOCK_URI, + FIRST_PROFILE_ID, + 1, + [], + freeCollectModule.address, + abiCoder.encode(['bool'], [true]), + ZERO_ADDRESS, + [], + await getTimestamp(), + ]); + }); + + it('Mirroring should emit the correct events', async function () { + await createProfile(); + + await waitForTx( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ); + await waitForTx( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ); + + receipt = await waitForTx( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ); + + expect(receipt.logs.length).to.eq(1); + + matchEvent(receipt, 'MirrorCreated', [ + FIRST_PROFILE_ID, + 2, + FIRST_PROFILE_ID, + 1, + [], + ZERO_ADDRESS, + [], + await getTimestamp(), + ]); + }); + + it('Following should emit correct events', async function () { + await createProfile(); + + await waitForTx( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ); + + const mockData = abiCoder.encode(['uint256'], [123]); + receipt = await waitForTx(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [mockData])); + const followNFT = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + + const expectedName = MOCK_PROFILE_HANDLE + '-Follower'; + const expectedSymbol = getAbbreviation(MOCK_PROFILE_HANDLE) + '-Fl'; + + expect(receipt.logs.length).to.eq(5); + matchEvent(receipt, 'FollowNFTDeployed', [FIRST_PROFILE_ID, followNFT, await getTimestamp()]); + matchEvent(receipt, 'Followed', [ + userTwoAddress, + [FIRST_PROFILE_ID], + [mockData], + await getTimestamp(), + ]); + matchEvent(receipt, 'Transfer', [ZERO_ADDRESS, userTwoAddress, 1], lensHubImpl); + matchEvent(receipt, 'FollowNFTTransferred', [ + FIRST_PROFILE_ID, + 1, + ZERO_ADDRESS, + userTwoAddress, + await getTimestamp(), + ]); + }); + + it('Collecting should emit correct events', async function () { + await createProfile(); + + await waitForTx( + lensHub.connect(governance).whitelistCollectModule(feeCollectModule.address, true) + ); + await expect( + moduleGlobals.connect(governance).whitelistCurrency(currency.address, true) + ).to.not.be.reverted; + + const collectPrice = 1; + const collectModuleInitData = abiCoder.encode( + ['uint256', 'address', 'address', 'uint16', 'bool'], + [collectPrice, currency.address, userAddress, 0, true] + ); + await waitForTx( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: feeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ); + + await waitForTx(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])); + + await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(userTwo).approve(feeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + const collectData = abiCoder.encode(['address', 'uint256'], [currency.address, collectPrice]); + receipt = await waitForTx(lensHub.connect(userTwo).collect(FIRST_PROFILE_ID, 1, collectData)); + const collectNFT = await lensHub.getCollectNFT(FIRST_PROFILE_ID, 1); + const expectedName = MOCK_PROFILE_HANDLE + '-Collect-' + '1'; + const expectedSymbol = getAbbreviation(MOCK_PROFILE_HANDLE) + '-Cl-' + '1'; + + expect(receipt.logs.length).to.eq(7); + matchEvent(receipt, 'CollectNFTDeployed', [ + FIRST_PROFILE_ID, + 1, + collectNFT, + await getTimestamp(), + ]); + matchEvent(receipt, 'Collected', [ + userTwoAddress, + FIRST_PROFILE_ID, + 1, + FIRST_PROFILE_ID, + 1, + collectData, + await getTimestamp(), + ]); + matchEvent(receipt, 'BaseInitialized', [expectedName, expectedSymbol, await getTimestamp()]); + matchEvent(receipt, 'CollectNFTInitialized', [FIRST_PROFILE_ID, 1, await getTimestamp()]); + matchEvent(receipt, 'Transfer', [ZERO_ADDRESS, userTwoAddress, 1], lensHubImpl); + matchEvent(receipt, 'CollectNFTTransferred', [ + FIRST_PROFILE_ID, + 1, + 1, + ZERO_ADDRESS, + userTwoAddress, + await getTimestamp(), + ]); + }); + + it('Collecting from a mirror should emit correct events', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + await createProfile(); + + await waitForTx( + lensHub.connect(governance).whitelistCollectModule(feeCollectModule.address, true) + ); + await expect( + moduleGlobals.connect(governance).whitelistCurrency(currency.address, true) + ).to.not.be.reverted; + + const collectPrice = 1; + const collectModuleInitData = abiCoder.encode( + ['uint256', 'address', 'address', 'uint16', 'bool'], + [collectPrice, currency.address, userAddress, 0, true] + ); + await waitForTx( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: feeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ); + + await waitForTx(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])); + + await waitForTx( + lensHub.connect(userTwo).createProfile({ + to: userTwoAddress, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ); + + await waitForTx( + lensHub.connect(userTwo).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ); + + await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(userTwo).approve(feeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + const collectData = abiCoder.encode(['address', 'uint256'], [currency.address, collectPrice]); + + receipt = await waitForTx(lensHub.connect(userTwo).collect(secondProfileId, 1, collectData)); + const collectNFT = await lensHub.getCollectNFT(FIRST_PROFILE_ID, 1); + const expectedName = MOCK_PROFILE_HANDLE + '-Collect-' + '1'; + const expectedSymbol = getAbbreviation(MOCK_PROFILE_HANDLE) + '-Cl-' + '1'; + + expect(receipt.logs.length).to.eq(7); + matchEvent(receipt, 'CollectNFTDeployed', [ + FIRST_PROFILE_ID, + 1, + collectNFT, + await getTimestamp(), + ]); + matchEvent(receipt, 'Collected', [ + userTwoAddress, + secondProfileId, + 1, + FIRST_PROFILE_ID, + 1, + collectData, + await getTimestamp(), + ]); + matchEvent(receipt, 'BaseInitialized', [expectedName, expectedSymbol, await getTimestamp()]); + matchEvent(receipt, 'CollectNFTInitialized', [FIRST_PROFILE_ID, 1, await getTimestamp()]); + matchEvent(receipt, 'Transfer', [ZERO_ADDRESS, userTwoAddress, 1], lensHubImpl); + matchEvent(receipt, 'CollectNFTTransferred', [ + FIRST_PROFILE_ID, + 1, + 1, + ZERO_ADDRESS, + userTwoAddress, + await getTimestamp(), + ]); + }); + }); + + context('Module Globals Governance', function () { + it('Governance change should emit expected event', async function () { + receipt = await waitForTx(moduleGlobals.connect(governance).setGovernance(userAddress)); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'ModuleGlobalsGovernanceSet', [ + governanceAddress, + userAddress, + await getTimestamp(), + ]); + }); + + it('Treasury change should emit expected event', async function () { + receipt = await waitForTx(moduleGlobals.connect(governance).setTreasury(userAddress)); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'ModuleGlobalsTreasurySet', [ + treasuryAddress, + userAddress, + await getTimestamp(), + ]); + }); + + it('Treasury fee change should emit expected event', async function () { + receipt = await waitForTx(moduleGlobals.connect(governance).setTreasuryFee(123)); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'ModuleGlobalsTreasuryFeeSet', [ + TREASURY_FEE_BPS, + 123, + await getTimestamp(), + ]); + }); + + it('Currency whitelisting should emit expected event', async function () { + receipt = await waitForTx( + moduleGlobals.connect(governance).whitelistCurrency(userAddress, true) + ); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'ModuleGlobalsCurrencyWhitelisted', [ + userAddress, + false, + true, + await getTimestamp(), + ]); + + receipt = await waitForTx( + moduleGlobals.connect(governance).whitelistCurrency(userAddress, false) + ); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'ModuleGlobalsCurrencyWhitelisted', [ + userAddress, + true, + false, + await getTimestamp(), + ]); + }); + }); +}); diff --git a/lens-protocol/core/test/other/misc.spec.ts b/lens-protocol/core/test/other/misc.spec.ts new file mode 100644 index 0000000..9080523 --- /dev/null +++ b/lens-protocol/core/test/other/misc.spec.ts @@ -0,0 +1,1254 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { FollowNFT__factory, UIDataProvider__factory } from '../../typechain-types'; +import { MAX_UINT256, ZERO_ADDRESS } from '../helpers/constants'; +import { ERRORS } from '../helpers/errors'; +import { + getDecodedSvgImage, + getMetadataFromBase64TokenUri, + getSetProfileMetadataURIWithSigParts, + getTimestamp, + getToggleFollowWithSigParts, + loadTestResourceAsUtf8String, + matchEvent, + waitForTx, +} from '../helpers/utils'; +import { + approvalFollowModule, + deployer, + freeCollectModule, + FIRST_PROFILE_ID, + followerOnlyReferenceModule, + governance, + governanceAddress, + lensHub, + makeSuiteCleanRoom, + mockFollowModule, + mockModuleData, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + moduleGlobals, + OTHER_MOCK_URI, + timedFeeCollectModule, + treasuryAddress, + TREASURY_FEE_BPS, + user, + userAddress, + userTwo, + userTwoAddress, + abiCoder, + userThree, + testWallet, + lensPeriphery, + followNFTImpl, + collectNFTImpl, +} from '../__setup.spec'; + +/** + * @dev Some of these tests may be redundant, but are still present to ensure an isolated environment, + * in particular if other test files are changed. + */ +makeSuiteCleanRoom('Misc', function () { + context('NFT Transfer Emitters', function () { + it('User should not be able to call the follow NFT transfer event emitter function', async function () { + await expect( + lensHub.emitFollowNFTTransferEvent(FIRST_PROFILE_ID, 1, userAddress, userTwoAddress) + ).to.be.revertedWith(ERRORS.NOT_FOLLOW_NFT); + }); + + it('User should not be able to call the collect NFT transfer event emitter function', async function () { + await expect( + lensHub.emitCollectNFTTransferEvent(FIRST_PROFILE_ID, 1, 1, userAddress, userTwoAddress) + ).to.be.revertedWith(ERRORS.NOT_COLLECT_NFT); + }); + }); + + context('Lens Hub Misc', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + it('UserTwo should fail to burn profile owned by user without being approved', async function () { + await expect(lensHub.connect(userTwo).burn(FIRST_PROFILE_ID)).to.be.revertedWith( + ERRORS.NOT_OWNER_OR_APPROVED + ); + }); + + it('User should burn profile owned by user', async function () { + await expect(lensHub.burn(FIRST_PROFILE_ID)).to.not.be.reverted; + }); + + it('UserTwo should burn profile owned by user if approved', async function () { + await expect(lensHub.approve(userTwoAddress, FIRST_PROFILE_ID)).to.not.be.reverted; + await expect(lensHub.connect(userTwo).burn(FIRST_PROFILE_ID)).to.not.be.reverted; + }); + + it('Governance getter should return proper address', async function () { + expect(await lensHub.getGovernance()).to.eq(governanceAddress); + }); + + it('Profile handle getter should return the correct handle', async function () { + expect(await lensHub.getHandle(FIRST_PROFILE_ID)).to.eq(MOCK_PROFILE_HANDLE); + }); + + it('Profile dispatcher getter should return the zero address when no dispatcher is set', async function () { + expect(await lensHub.getDispatcher(FIRST_PROFILE_ID)).to.eq(ZERO_ADDRESS); + }); + + it('Profile creator whitelist getter should return expected values', async function () { + expect(await lensHub.isProfileCreatorWhitelisted(userAddress)).to.eq(true); + await expect( + lensHub.connect(governance).whitelistProfileCreator(userAddress, false) + ).to.not.be.reverted; + expect(await lensHub.isProfileCreatorWhitelisted(userAddress)).to.eq(false); + }); + + it('Profile dispatcher getter should return the correct dispatcher address when it is set, then zero after it is transferred', async function () { + await expect(lensHub.setDispatcher(FIRST_PROFILE_ID, userTwoAddress)).to.not.be.reverted; + expect(await lensHub.getDispatcher(FIRST_PROFILE_ID)).to.eq(userTwoAddress); + + await expect( + lensHub.transferFrom(userAddress, userTwoAddress, FIRST_PROFILE_ID) + ).to.not.be.reverted; + expect(await lensHub.getDispatcher(FIRST_PROFILE_ID)).to.eq(ZERO_ADDRESS); + }); + + it('Profile follow NFT getter should return the zero address before the first follow, then the correct address afterwards', async function () { + expect(await lensHub.getFollowNFT(FIRST_PROFILE_ID)).to.eq(ZERO_ADDRESS); + + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + + expect(await lensHub.getFollowNFT(FIRST_PROFILE_ID)).to.not.eq(ZERO_ADDRESS); + }); + + it('Profile follow module getter should return the zero address, then the correct follow module after it is set', async function () { + expect(await lensHub.getFollowModule(FIRST_PROFILE_ID)).to.eq(ZERO_ADDRESS); + + await expect( + lensHub.connect(governance).whitelistFollowModule(mockFollowModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.setFollowModule(FIRST_PROFILE_ID, mockFollowModule.address, mockModuleData) + ).to.not.be.reverted; + expect(await lensHub.getFollowModule(FIRST_PROFILE_ID)).to.eq(mockFollowModule.address); + }); + + it('Profile publication count getter should return zero, then the correct amount after some publications', async function () { + expect(await lensHub.getPubCount(FIRST_PROFILE_ID)).to.eq(0); + + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + const expectedCount = 5; + for (let i = 0; i < expectedCount; i++) { + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + } + expect(await lensHub.getPubCount(FIRST_PROFILE_ID)).to.eq(expectedCount); + }); + + it('Follow NFT impl getter should return the correct address', async function () { + expect(await lensHub.getFollowNFTImpl()).to.eq(followNFTImpl.address); + }); + + it('Collect NFT impl getter should return the correct address', async function () { + expect(await lensHub.getCollectNFTImpl()).to.eq(collectNFTImpl.address); + }); + + it('Profile tokenURI should return the accurate URI', async function () { + const tokenUri = await lensHub.tokenURI(FIRST_PROFILE_ID); + const metadata = await getMetadataFromBase64TokenUri(tokenUri); + expect(metadata.name).to.eq(`@${MOCK_PROFILE_HANDLE}`); + expect(metadata.description).to.eq(`@${MOCK_PROFILE_HANDLE} - Lens profile`); + const expectedAttributes = [ + { trait_type: 'id', value: `#${FIRST_PROFILE_ID.toString()}` }, + { trait_type: 'followers', value: '0' }, + { trait_type: 'owner', value: userAddress.toLowerCase() }, + { trait_type: 'handle', value: `@${MOCK_PROFILE_HANDLE}` }, + ]; + expect(metadata.attributes).to.eql(expectedAttributes); + const actualSvg = await getDecodedSvgImage(metadata); + const expectedSvg = loadTestResourceAsUtf8String('profile-token-uri-images/mock-profile.svg'); + expect(actualSvg).to.eq(expectedSvg); + }); + + it('Publication reference module getter should return the correct reference module (or zero in case of no reference module)', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub + .connect(governance) + .whitelistReferenceModule(followerOnlyReferenceModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + expect(await lensHub.getReferenceModule(FIRST_PROFILE_ID, 1)).to.eq(ZERO_ADDRESS); + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: followerOnlyReferenceModule.address, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + expect(await lensHub.getReferenceModule(FIRST_PROFILE_ID, 2)).to.eq( + followerOnlyReferenceModule.address + ); + }); + + it('Publication pointer getter should return an empty pointer for posts', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const pointer = await lensHub.getPubPointer(FIRST_PROFILE_ID, 1); + expect(pointer[0]).to.eq(0); + expect(pointer[1]).to.eq(0); + }); + + it('Publication pointer getter should return the correct pointer for comments', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const pointer = await lensHub.getPubPointer(FIRST_PROFILE_ID, 2); + expect(pointer[0]).to.eq(FIRST_PROFILE_ID); + expect(pointer[1]).to.eq(1); + }); + + it('Publication pointer getter should return the correct pointer for mirrors', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const pointer = await lensHub.getPubPointer(FIRST_PROFILE_ID, 2); + expect(pointer[0]).to.eq(FIRST_PROFILE_ID); + expect(pointer[1]).to.eq(1); + }); + + it('Publication content URI getter should return the correct URI for posts', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + expect(await lensHub.getContentURI(FIRST_PROFILE_ID, 1)).to.eq(MOCK_URI); + }); + + it('Publication content URI getter should return the correct URI for comments', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: OTHER_MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + expect(await lensHub.getContentURI(FIRST_PROFILE_ID, 2)).to.eq(OTHER_MOCK_URI); + }); + + it('Publication content URI getter should return the correct URI for mirrors', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + expect(await lensHub.getContentURI(FIRST_PROFILE_ID, 2)).to.eq(MOCK_URI); + }); + + it('Publication collect module getter should return the correct collectModule for posts', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + expect(await lensHub.getCollectModule(FIRST_PROFILE_ID, 1)).to.eq(freeCollectModule.address); + }); + + it('Publication collect module getter should return the correct collectModule for comments', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: OTHER_MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 2, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + expect(await lensHub.getCollectModule(FIRST_PROFILE_ID, 3)).to.eq(freeCollectModule.address); + }); + + it('Publication collect module getter should return the zero address for mirrors', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + expect(await lensHub.getCollectModule(FIRST_PROFILE_ID, 2)).to.eq(ZERO_ADDRESS); + }); + + it('Publication type getter should return the correct publication type for all publication types, or nonexistent', async function () { + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.comment({ + profileId: FIRST_PROFILE_ID, + contentURI: OTHER_MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.mirror({ + profileId: FIRST_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModuleData: [], + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + expect(await lensHub.getPubType(FIRST_PROFILE_ID, 1)).to.eq(0); + expect(await lensHub.getPubType(FIRST_PROFILE_ID, 2)).to.eq(1); + expect(await lensHub.getPubType(FIRST_PROFILE_ID, 3)).to.eq(2); + expect(await lensHub.getPubType(FIRST_PROFILE_ID, 4)).to.eq(3); + }); + + it('Profile getter should return accurate profile parameters', async function () { + const fetchedProfile = await lensHub.getProfile(FIRST_PROFILE_ID); + expect(fetchedProfile.pubCount).to.eq(0); + expect(fetchedProfile.handle).to.eq(MOCK_PROFILE_HANDLE); + expect(fetchedProfile.followModule).to.eq(ZERO_ADDRESS); + expect(fetchedProfile.followNFT).to.eq(ZERO_ADDRESS); + }); + }); + + context('Follow Module Misc', function () { + beforeEach(async function () { + await expect( + lensHub.connect(governance).whitelistFollowModule(approvalFollowModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: approvalFollowModule.address, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + it('User should fail to call processFollow directly on a follow module inheriting from the FollowValidatorFollowModuleBase', async function () { + await expect(approvalFollowModule.processFollow(ZERO_ADDRESS, 0, [])).to.be.revertedWith( + ERRORS.NOT_HUB + ); + }); + + it('Follow module following check when there are no follows, and thus no deployed Follow NFT should return false', async function () { + expect( + await approvalFollowModule.isFollowing(FIRST_PROFILE_ID, userTwoAddress, 0) + ).to.be.false; + }); + + it('Follow module following check with zero ID input should return false after another address follows, but not the queried address', async function () { + await expect( + approvalFollowModule.connect(user).approve(FIRST_PROFILE_ID, [userAddress], [true]) + ).to.not.be.reverted; + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + + expect( + await approvalFollowModule.isFollowing(FIRST_PROFILE_ID, userTwoAddress, 0) + ).to.be.false; + }); + + it('Follow module following check with specific ID input should revert after following, but the specific ID does not exist yet', async function () { + await expect( + approvalFollowModule.connect(user).approve(FIRST_PROFILE_ID, [userAddress], [true]) + ).to.not.be.reverted; + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + + await expect( + approvalFollowModule.isFollowing(FIRST_PROFILE_ID, userAddress, 2) + ).to.be.revertedWith(ERRORS.ERC721_QUERY_FOR_NONEXISTENT_TOKEN); + }); + + it('Follow module following check with specific ID input should return false if another address owns the specified follow NFT', async function () { + await expect( + approvalFollowModule.connect(user).approve(FIRST_PROFILE_ID, [userAddress], [true]) + ).to.not.be.reverted; + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + + expect( + await approvalFollowModule.isFollowing(FIRST_PROFILE_ID, userTwoAddress, 1) + ).to.be.false; + }); + + it('Follow module following check with specific ID input should return true if the queried address owns the specified follow NFT', async function () { + await expect( + approvalFollowModule.connect(user).approve(FIRST_PROFILE_ID, [userAddress], [true]) + ).to.not.be.reverted; + await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + + expect(await approvalFollowModule.isFollowing(FIRST_PROFILE_ID, userAddress, 1)).to.be.true; + }); + }); + + context('Collect Module Misc', function () { + it('Should fail to call processCollect directly on a collect module inheriting from the FollowValidationModuleBase contract', async function () { + await expect( + timedFeeCollectModule.processCollect(0, ZERO_ADDRESS, 0, 0, []) + ).to.be.revertedWith(ERRORS.NOT_HUB); + }); + }); + + context('Module Globals', function () { + context('Negatives', function () { + it('User should fail to set the governance address on the module globals', async function () { + await expect(moduleGlobals.connect(user).setGovernance(ZERO_ADDRESS)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE + ); + }); + + it('User should fail to set the treasury on the module globals', async function () { + await expect(moduleGlobals.connect(user).setTreasury(ZERO_ADDRESS)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE + ); + }); + + it('User should fail to set the treasury fee on the module globals', async function () { + await expect(moduleGlobals.connect(user).setTreasuryFee(0)).to.be.revertedWith( + ERRORS.NOT_GOVERNANCE + ); + }); + }); + + context('Scenarios', function () { + it('Governance should set the governance address on the module globals', async function () { + await expect( + moduleGlobals.connect(governance).setGovernance(userAddress) + ).to.not.be.reverted; + }); + + it('Governance should set the treasury on the module globals', async function () { + await expect(moduleGlobals.connect(governance).setTreasury(userAddress)).to.not.be.reverted; + }); + + it('Governance should set the treasury fee on the module globals', async function () { + await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted; + }); + + it('Governance should fail to whitelist the zero address as a currency', async function () { + await expect( + moduleGlobals.connect(governance).whitelistCurrency(ZERO_ADDRESS, true) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('Governance getter should return expected address', async function () { + expect(await moduleGlobals.getGovernance()).to.eq(governanceAddress); + }); + + it('Treasury getter should return expected address', async function () { + expect(await moduleGlobals.getTreasury()).to.eq(treasuryAddress); + }); + + it('Treasury fee getter should return the expected fee', async function () { + expect(await moduleGlobals.getTreasuryFee()).to.eq(TREASURY_FEE_BPS); + }); + }); + }); + + context('UI Data Provider', function () { + it('UI Data Provider should return expected values', async function () { + // First, create a profile, + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + // Then, whitelist a collect module + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + + // Then, publish twice + const firstURI = 'first publication'; + const secondURI = 'second publication'; + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: firstURI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.post({ + profileId: FIRST_PROFILE_ID, + contentURI: secondURI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + // Then, deploy the data provider + const lensPeriphery = await new UIDataProvider__factory(deployer).deploy(lensHub.address); + + // `getLatestDataByProfile`, validate the result from the data provider + const resultByProfileId = await lensPeriphery.getLatestDataByProfile(FIRST_PROFILE_ID); + const pubByProfileIdStruct = resultByProfileId.publicationStruct; + const profileByProfileIdStruct = resultByProfileId.profileStruct; + + expect(profileByProfileIdStruct.pubCount).to.eq(2); + expect(profileByProfileIdStruct.followModule).to.eq(ZERO_ADDRESS); + expect(profileByProfileIdStruct.followNFT).to.eq(ZERO_ADDRESS); + expect(profileByProfileIdStruct.handle).to.eq(MOCK_PROFILE_HANDLE); + expect(profileByProfileIdStruct.imageURI).to.eq(MOCK_PROFILE_URI); + expect(profileByProfileIdStruct.followNFTURI).to.eq(MOCK_FOLLOW_NFT_URI); + + expect(pubByProfileIdStruct.profileIdPointed).to.eq(0); + expect(pubByProfileIdStruct.pubIdPointed).to.eq(0); + expect(pubByProfileIdStruct.contentURI).to.eq(secondURI); + expect(pubByProfileIdStruct.referenceModule).to.eq(ZERO_ADDRESS); + expect(pubByProfileIdStruct.collectModule).to.eq(freeCollectModule.address); + expect(pubByProfileIdStruct.collectNFT).to.eq(ZERO_ADDRESS); + + // `getLatestDataByHandle`, validate the result from the data provider + const resultByHandle = await lensPeriphery.getLatestDataByHandle(MOCK_PROFILE_HANDLE); + const pubByHandleStruct = resultByHandle.publicationStruct; + const profileByHandleStruct = resultByHandle.profileStruct; + + expect(profileByHandleStruct.pubCount).to.eq(2); + expect(profileByHandleStruct.followModule).to.eq(ZERO_ADDRESS); + expect(profileByHandleStruct.followNFT).to.eq(ZERO_ADDRESS); + expect(profileByHandleStruct.handle).to.eq(MOCK_PROFILE_HANDLE); + expect(profileByHandleStruct.imageURI).to.eq(MOCK_PROFILE_URI); + expect(profileByHandleStruct.followNFTURI).to.eq(MOCK_FOLLOW_NFT_URI); + + expect(pubByHandleStruct.profileIdPointed).to.eq(0); + expect(pubByHandleStruct.pubIdPointed).to.eq(0); + expect(pubByHandleStruct.contentURI).to.eq(secondURI); + expect(pubByHandleStruct.referenceModule).to.eq(ZERO_ADDRESS); + expect(pubByHandleStruct.collectModule).to.eq(freeCollectModule.address); + expect(pubByHandleStruct.collectNFT).to.eq(ZERO_ADDRESS); + }); + }); + + context('LensPeriphery', async function () { + context('ToggleFollowing', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + await expect( + lensHub.connect(userThree).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + await expect( + lensHub.connect(testWallet).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + }); + + context('Generic', function () { + context('Negatives', function () { + it('UserTwo should fail to toggle follow with an incorrect profileId', async function () { + await expect( + lensPeriphery.connect(userTwo).toggleFollow([FIRST_PROFILE_ID + 1], [true]) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('UserTwo should fail to toggle follow with array mismatch', async function () { + await expect( + lensPeriphery.connect(userTwo).toggleFollow([FIRST_PROFILE_ID, FIRST_PROFILE_ID], []) + ).to.be.revertedWith(ERRORS.ARRAY_MISMATCH); + }); + + it('UserTwo should fail to toggle follow from a profile that has been burned', async function () { + await expect(lensHub.burn(FIRST_PROFILE_ID)).to.not.be.reverted; + await expect( + lensPeriphery.connect(userTwo).toggleFollow([FIRST_PROFILE_ID], [true]) + ).to.be.revertedWith(ERRORS.TOKEN_DOES_NOT_EXIST); + }); + + it('UserTwo should fail to toggle follow for a followNFT that is not owned by them', async function () { + const followNFTAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNFT = FollowNFT__factory.connect(followNFTAddress, user); + + await expect( + followNFT.connect(userTwo).transferFrom(userTwoAddress, userAddress, 1) + ).to.not.be.reverted; + + await expect( + lensPeriphery.connect(userTwo).toggleFollow([FIRST_PROFILE_ID], [true]) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + }); + + context('Scenarios', function () { + it('UserTwo should toggle follow with true value, correct event should be emitted', async function () { + const tx = lensPeriphery.connect(userTwo).toggleFollow([FIRST_PROFILE_ID], [true]); + + const receipt = await waitForTx(tx); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'FollowsToggled', [ + userTwoAddress, + [FIRST_PROFILE_ID], + [true], + await getTimestamp(), + ]); + }); + + it('User should create another profile, userTwo follows, then toggles both, one true, one false, correct event should be emitted', async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: 'otherhandle', + imageURI: OTHER_MOCK_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(userTwo).follow([FIRST_PROFILE_ID + 1], [[]]) + ).to.not.be.reverted; + + const tx = lensPeriphery + .connect(userTwo) + .toggleFollow([FIRST_PROFILE_ID, FIRST_PROFILE_ID + 1], [true, false]); + + const receipt = await waitForTx(tx); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'FollowsToggled', [ + userTwoAddress, + [FIRST_PROFILE_ID, FIRST_PROFILE_ID + 1], + [true, false], + await getTimestamp(), + ]); + }); + + it('UserTwo should toggle follow with false value, correct event should be emitted', async function () { + const tx = lensPeriphery.connect(userTwo).toggleFollow([FIRST_PROFILE_ID], [false]); + + const receipt = await waitForTx(tx); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'FollowsToggled', [ + userTwoAddress, + [FIRST_PROFILE_ID], + [false], + await getTimestamp(), + ]); + }); + }); + }); + + context('Meta-tx', function () { + context('Negatives', function () { + it('TestWallet should fail to toggle follow with sig with signature deadline mismatch', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getToggleFollowWithSigParts( + [FIRST_PROFILE_ID], + [true], + nonce, + '0' + ); + await expect( + lensPeriphery.toggleFollowWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + enables: [true], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should fail to toggle follow with sig with invalid deadline', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getToggleFollowWithSigParts( + [FIRST_PROFILE_ID], + [true], + nonce, + '0' + ); + await expect( + lensPeriphery.toggleFollowWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + enables: [true], + sig: { + v, + r, + s, + deadline: '0', + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('TestWallet should fail to toggle follow with sig with invalid nonce', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getToggleFollowWithSigParts( + [FIRST_PROFILE_ID], + [true], + nonce + 1, + MAX_UINT256 + ); + + await expect( + lensPeriphery.toggleFollowWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + enables: [true], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should fail to toggle follow a nonexistent profile with sig', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + const INVALID_PROFILE = FIRST_PROFILE_ID + 1; + const { v, r, s } = await getToggleFollowWithSigParts( + [INVALID_PROFILE], + [true], + nonce, + MAX_UINT256 + ); + await expect( + lensPeriphery.toggleFollowWithSig({ + follower: testWallet.address, + profileIds: [INVALID_PROFILE], + enables: [true], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + }); + + context('Scenarios', function () { + it('TestWallet should toggle follow profile 1 to true with sig, correct event should be emitted ', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getToggleFollowWithSigParts( + [FIRST_PROFILE_ID], + [true], + nonce, + MAX_UINT256 + ); + + const tx = lensPeriphery.toggleFollowWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + enables: [true], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }); + + const receipt = await waitForTx(tx); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'FollowsToggled', [ + testWallet.address, + [FIRST_PROFILE_ID], + [true], + await getTimestamp(), + ]); + }); + + it('TestWallet should toggle follow profile 1 to false with sig, correct event should be emitted ', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + + const enabled = false; + const { v, r, s } = await getToggleFollowWithSigParts( + [FIRST_PROFILE_ID], + [enabled], + nonce, + MAX_UINT256 + ); + + const tx = lensPeriphery.toggleFollowWithSig({ + follower: testWallet.address, + profileIds: [FIRST_PROFILE_ID], + enables: [enabled], + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }); + + const receipt = await waitForTx(tx); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'FollowsToggled', [ + testWallet.address, + [FIRST_PROFILE_ID], + [enabled], + await getTimestamp(), + ]); + }); + }); + }); + }); + + context('Profile Metadata URI', function () { + const MOCK_DATA = 'd171c8b1d364bb34553299ab686caa41ac7a2209d4a63e25947764080c4681da'; + + context('Generic', function () { + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('User two should fail to set profile metadata URI for a profile that is not theirs while they are not the dispatcher', async function () { + await expect( + lensPeriphery.connect(userTwo).setProfileMetadataURI(FIRST_PROFILE_ID, MOCK_DATA) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER_OR_DISPATCHER); + }); + }); + + context('Scenarios', function () { + it("User should set user two as dispatcher, user two should set profile metadata URI for user one's profile, fetched data should be accurate", async function () { + await expect( + lensHub.setDispatcher(FIRST_PROFILE_ID, userTwoAddress) + ).to.not.be.reverted; + await expect( + lensPeriphery.connect(userTwo).setProfileMetadataURI(FIRST_PROFILE_ID, MOCK_DATA) + ).to.not.be.reverted; + + expect(await lensPeriphery.getProfileMetadataURI(FIRST_PROFILE_ID)).to.eq(MOCK_DATA); + expect(await lensPeriphery.getProfileMetadataURI(FIRST_PROFILE_ID)).to.eq(MOCK_DATA); + }); + + it('Setting profile metadata should emit the correct event', async function () { + const tx = await waitForTx( + lensPeriphery.setProfileMetadataURI(FIRST_PROFILE_ID, MOCK_DATA) + ); + + matchEvent(tx, 'ProfileMetadataSet', [ + FIRST_PROFILE_ID, + MOCK_DATA, + await getTimestamp(), + ]); + }); + + it('Setting profile metadata via dispatcher should emit the correct event', async function () { + await expect( + lensHub.setDispatcher(FIRST_PROFILE_ID, userTwoAddress) + ).to.not.be.reverted; + + const tx = await waitForTx( + lensPeriphery.connect(userTwo).setProfileMetadataURI(FIRST_PROFILE_ID, MOCK_DATA) + ); + + matchEvent(tx, 'ProfileMetadataSet', [ + FIRST_PROFILE_ID, + MOCK_DATA, + await getTimestamp(), + ]); + }); + }); + }); + + context('Meta-tx', async function () { + beforeEach(async function () { + await expect( + lensHub.connect(testWallet).createProfile({ + to: testWallet.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Negatives', async function () { + it('TestWallet should fail to set profile metadata URI with sig with signature deadline mismatch', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getSetProfileMetadataURIWithSigParts( + FIRST_PROFILE_ID, + MOCK_DATA, + nonce, + '0' + ); + await expect( + lensPeriphery.setProfileMetadataURIWithSig({ + profileId: FIRST_PROFILE_ID, + metadata: MOCK_DATA, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('TestWallet should fail to set profile metadata URI with sig with invalid deadline', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getSetProfileMetadataURIWithSigParts( + FIRST_PROFILE_ID, + MOCK_DATA, + nonce, + '0' + ); + await expect( + lensPeriphery.setProfileMetadataURIWithSig({ + profileId: FIRST_PROFILE_ID, + metadata: MOCK_DATA, + sig: { + v, + r, + s, + deadline: '0', + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('TestWallet should fail to set profile metadata URI with sig with invalid nonce', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getSetProfileMetadataURIWithSigParts( + FIRST_PROFILE_ID, + MOCK_DATA, + nonce + 1, + MAX_UINT256 + ); + await expect( + lensPeriphery.setProfileMetadataURIWithSig({ + profileId: FIRST_PROFILE_ID, + metadata: MOCK_DATA, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + it('TestWallet should set profile metadata URI with sig, fetched data should be accurate and correct event should be emitted', async function () { + const nonce = (await lensPeriphery.sigNonces(testWallet.address)).toNumber(); + + const { v, r, s } = await getSetProfileMetadataURIWithSigParts( + FIRST_PROFILE_ID, + MOCK_DATA, + nonce, + MAX_UINT256 + ); + const tx = await waitForTx( + lensPeriphery.setProfileMetadataURIWithSig({ + profileId: FIRST_PROFILE_ID, + metadata: MOCK_DATA, + sig: { + v, + r, + s, + deadline: MAX_UINT256, + }, + }) + ); + + expect(await lensPeriphery.getProfileMetadataURI(FIRST_PROFILE_ID)).to.eq(MOCK_DATA); + expect(await lensPeriphery.getProfileMetadataURI(FIRST_PROFILE_ID)).to.eq(MOCK_DATA); + + matchEvent(tx, 'ProfileMetadataSet', [ + FIRST_PROFILE_ID, + MOCK_DATA, + await getTimestamp(), + ]); + }); + }); + }); + }); + }); +}); diff --git a/lens-protocol/core/test/other/mock-profile-creation-proxy.spec.ts b/lens-protocol/core/test/other/mock-profile-creation-proxy.spec.ts new file mode 100644 index 0000000..3dc3981 --- /dev/null +++ b/lens-protocol/core/test/other/mock-profile-creation-proxy.spec.ts @@ -0,0 +1,136 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { ZERO_ADDRESS } from '../helpers/constants'; +import { ERRORS } from '../helpers/errors'; +import { MockProfileCreationProxy, MockProfileCreationProxy__factory } from '../../typechain-types'; +import { + deployer, + FIRST_PROFILE_ID, + governance, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_URI, + user, + userAddress, + deployerAddress, +} from '../__setup.spec'; +import { BigNumber } from 'ethers'; +import { TokenDataStructOutput } from '../../typechain-types/LensHub'; +import { getTimestamp } from '../helpers/utils'; + +makeSuiteCleanRoom('Mock Profile Creation Proxy', function () { + const REQUIRED_SUFFIX = '.test'; + const MINIMUM_LENGTH = 5; + + let profileCreationProxy: MockProfileCreationProxy; + beforeEach(async function () { + profileCreationProxy = await new MockProfileCreationProxy__factory(deployer).deploy( + lensHub.address + ); + await expect( + lensHub.connect(governance).whitelistProfileCreator(profileCreationProxy.address, true) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('Should fail to create profile if handle length before suffix does not reach minimum length', async function () { + const handle = 'a'.repeat(MINIMUM_LENGTH - 1); + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: handle, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.INVALID_HANDLE_LENGTH); + }); + + it('Should fail to create profile if handle contains an invalid character before the suffix', async function () { + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: 'dots.are.invalid', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_CONTAINS_INVALID_CHARACTERS); + }); + + it('Should fail to create profile if handle starts with a dash, underscore or period', async function () { + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: '.abcdef', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_FIRST_CHARACTER_INVALID); + + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: '-abcdef', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_FIRST_CHARACTER_INVALID); + + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: '_abcdef', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_FIRST_CHARACTER_INVALID); + }); + }); + + context('Scenarios', function () { + it('Should be able to create a profile using the whitelisted proxy, received NFT should be valid', async function () { + let timestamp: any; + let owner: string; + let totalSupply: BigNumber; + let profileId: BigNumber; + let mintTimestamp: BigNumber; + let tokenData: TokenDataStructOutput; + const validHandleBeforeSuffix = 'v_al-id'; + const expectedHandle = 'v_al-id'.concat(REQUIRED_SUFFIX); + + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: validHandleBeforeSuffix, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + timestamp = await getTimestamp(); + owner = await lensHub.ownerOf(FIRST_PROFILE_ID); + totalSupply = await lensHub.totalSupply(); + profileId = await lensHub.getProfileIdByHandle(expectedHandle); + mintTimestamp = await lensHub.mintTimestampOf(FIRST_PROFILE_ID); + tokenData = await lensHub.tokenDataOf(FIRST_PROFILE_ID); + expect(owner).to.eq(userAddress); + expect(totalSupply).to.eq(FIRST_PROFILE_ID); + expect(profileId).to.eq(FIRST_PROFILE_ID); + expect(mintTimestamp).to.eq(timestamp); + expect(tokenData.owner).to.eq(userAddress); + expect(tokenData.mintTimestamp).to.eq(timestamp); + }); + }); +}); diff --git a/lens-protocol/core/test/other/profile-creation-proxy.spec.ts b/lens-protocol/core/test/other/profile-creation-proxy.spec.ts new file mode 100644 index 0000000..f3ad932 --- /dev/null +++ b/lens-protocol/core/test/other/profile-creation-proxy.spec.ts @@ -0,0 +1,137 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { ZERO_ADDRESS } from '../helpers/constants'; +import { ERRORS } from '../helpers/errors'; +import { ProfileCreationProxy, ProfileCreationProxy__factory } from '../../typechain-types'; +import { + deployer, + FIRST_PROFILE_ID, + governance, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_URI, + user, + userAddress, + deployerAddress, +} from '../__setup.spec'; +import { BigNumber } from 'ethers'; +import { TokenDataStructOutput } from '../../typechain-types/LensHub'; +import { getTimestamp } from '../helpers/utils'; + +makeSuiteCleanRoom('Profile Creation Proxy', function () { + const REQUIRED_SUFFIX = '.lens'; + const MINIMUM_LENGTH = 5; + + let profileCreationProxy: ProfileCreationProxy; + beforeEach(async function () { + profileCreationProxy = await new ProfileCreationProxy__factory(deployer).deploy( + deployerAddress, + lensHub.address + ); + await expect( + lensHub.connect(governance).whitelistProfileCreator(profileCreationProxy.address, true) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('Should fail to create profile if handle length before suffix does not reach minimum length', async function () { + const handle = 'a'.repeat(MINIMUM_LENGTH - 1); + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: handle, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.INVALID_HANDLE_LENGTH); + }); + + it('Should fail to create profile if handle contains an invalid character before the suffix', async function () { + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: 'dots.are.invalid', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_CONTAINS_INVALID_CHARACTERS); + }); + + it('Should fail to create profile if handle starts with a dash, underscore or period', async function () { + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: '.abcdef', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_FIRST_CHARACTER_INVALID); + + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: '-abcdef', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_FIRST_CHARACTER_INVALID); + + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: '_abcdef', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.be.revertedWith(ERRORS.HANDLE_FIRST_CHARACTER_INVALID); + }); + }); + + context('Scenarios', function () { + it('Should be able to create a profile using the whitelisted proxy, received NFT should be valid', async function () { + let timestamp: any; + let owner: string; + let totalSupply: BigNumber; + let profileId: BigNumber; + let mintTimestamp: BigNumber; + let tokenData: TokenDataStructOutput; + const validHandleBeforeSuffix = 'v_al-id'; + const expectedHandle = 'v_al-id'.concat(REQUIRED_SUFFIX); + + await expect( + profileCreationProxy.proxyCreateProfile({ + to: userAddress, + handle: validHandleBeforeSuffix, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + timestamp = await getTimestamp(); + owner = await lensHub.ownerOf(FIRST_PROFILE_ID); + totalSupply = await lensHub.totalSupply(); + profileId = await lensHub.getProfileIdByHandle(expectedHandle); + mintTimestamp = await lensHub.mintTimestampOf(FIRST_PROFILE_ID); + tokenData = await lensHub.tokenDataOf(FIRST_PROFILE_ID); + expect(owner).to.eq(userAddress); + expect(totalSupply).to.eq(FIRST_PROFILE_ID); + expect(profileId).to.eq(FIRST_PROFILE_ID); + expect(mintTimestamp).to.eq(timestamp); + expect(tokenData.owner).to.eq(userAddress); + expect(tokenData.mintTimestamp).to.eq(timestamp); + }); + }); +}); diff --git a/lens-protocol/core/test/other/upgradeability.spec.ts b/lens-protocol/core/test/other/upgradeability.spec.ts new file mode 100644 index 0000000..ba759d8 --- /dev/null +++ b/lens-protocol/core/test/other/upgradeability.spec.ts @@ -0,0 +1,123 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { + MockLensHubV2BadRevision__factory, + MockLensHubV2__factory, + MockAccessControlV2BadRevision__factory, + AccessControlV2__factory, + AccessControl__factory, + TransparentUpgradeableProxy__factory, +} from '../../typechain-types'; +import { ZERO_ADDRESS } from '../helpers/constants'; +import { ERRORS } from '../helpers/errors'; +import { + abiCoder, + deployer, + deployerAddress, + FIRST_PROFILE_ID, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + user, + userAddress, + userTwoAddress, +} from '../__setup.spec'; + +makeSuiteCleanRoom('Upgradeability', function () { + const valueToSet = 123; + + it('Should fail to initialize an implementation with the same revision', async function () { + const newImpl = await new MockLensHubV2BadRevision__factory(deployer).deploy(); + const proxyHub = TransparentUpgradeableProxy__factory.connect(lensHub.address, deployer); + const hub = MockLensHubV2BadRevision__factory.connect(proxyHub.address, user); + await expect(proxyHub.upgradeTo(newImpl.address)).to.not.be.reverted; + await expect(hub.initialize(valueToSet)).to.be.revertedWith(ERRORS.INITIALIZED); + }); + + // The LensHub contract's last storage variable by default is at the 23nd slot (index 22) and contains the emergency admin + // We're going to validate the first 23 slots and the 24rd slot before and after the change + it("Should upgrade and set a new variable's value, previous storage is unchanged, new value is accurate", async function () { + const newImpl = await new MockLensHubV2__factory(deployer).deploy(); + const proxyHub = TransparentUpgradeableProxy__factory.connect(lensHub.address, deployer); + + const prevStorage: string[] = []; + for (let i = 0; i < 24; i++) { + const valueAt = await ethers.provider.getStorageAt(proxyHub.address, i); + prevStorage.push(valueAt); + } + + const prevNextSlot = await ethers.provider.getStorageAt(proxyHub.address, 24); + const formattedZero = abiCoder.encode(['uint256'], [0]); + expect(prevNextSlot).to.eq(formattedZero); + + await proxyHub.upgradeTo(newImpl.address); + await expect( + MockLensHubV2__factory.connect(proxyHub.address, user).setAdditionalValue(valueToSet) + ).to.not.be.reverted; + + for (let i = 0; i < 24; i++) { + const valueAt = await ethers.provider.getStorageAt(proxyHub.address, i); + expect(valueAt).to.eq(prevStorage[i]); + } + + const newNextSlot = await ethers.provider.getStorageAt(proxyHub.address, 24); + const formattedValue = abiCoder.encode(['uint256'], [valueToSet]); + expect(newNextSlot).to.eq(formattedValue); + }); + + context('AccessControl Upgradability', function () { + let accessControl, accessControlImpl, accessControlProxy; + before(async function () { + accessControlImpl = await new AccessControl__factory(deployer).deploy(lensHub.address); + + const data = accessControlImpl.interface.encodeFunctionData('initialize', []); + + accessControlProxy = await new TransparentUpgradeableProxy__factory(deployer).deploy( + accessControlImpl.address, + deployerAddress, + data + ); + + accessControl = AccessControl__factory.connect(accessControlProxy.address, user); + }); + + beforeEach(async function () { + await lensHub.createProfile({ + to: userAddress, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + }); + + it('AccessControl upgrade should fail to initialize an implementation with the same revision', async function () { + const newImpl = await new MockAccessControlV2BadRevision__factory(deployer).deploy( + lensHub.address + ); + await expect(accessControlProxy.upgradeTo(newImpl.address)).to.not.be.reverted; + await expect(accessControl.initialize()).to.be.revertedWith(ERRORS.INITIALIZED); + }); + + it('AccessControl upgrade should behave as expected before and after being upgraded', async function () { + expect(await lensHub.ownerOf(FIRST_PROFILE_ID)).to.be.eq(userAddress); + expect(await accessControl.hasAccess(userAddress, FIRST_PROFILE_ID, [])).to.be.true; + expect(await accessControl.hasAccess(userTwoAddress, FIRST_PROFILE_ID, [])).to.be.false; + + const newImpl = await new AccessControlV2__factory(deployer).deploy(lensHub.address); + const data = accessControlImpl.interface.encodeFunctionData('initialize', []); + await expect(accessControlProxy.upgradeToAndCall(newImpl.address, data)).to.not.be.reverted; + await expect(accessControl.initialize()).to.be.revertedWith(ERRORS.INITIALIZED); + + expect(await lensHub.ownerOf(FIRST_PROFILE_ID)).to.be.eq(userAddress); + expect(await accessControl.hasAccess(userAddress, FIRST_PROFILE_ID, [])).to.be.true; + expect(await accessControl.hasAccess(userTwoAddress, FIRST_PROFILE_ID, [])).to.be.false; + + // See access-control.spec.ts tests for thorough upgrade testing. + }); + }); +}); diff --git a/lens-protocol/core/test/resources/profile-token-uri-images/default.svg b/lens-protocol/core/test/resources/profile-token-uri-images/default.svg new file mode 100644 index 0000000..f1720e2 --- /dev/null +++ b/lens-protocol/core/test/resources/profile-token-uri-images/default.svg @@ -0,0 +1 @@ +@plant1ghost.eth \ No newline at end of file diff --git a/lens-protocol/core/test/resources/profile-token-uri-images/mock-profile.svg b/lens-protocol/core/test/resources/profile-token-uri-images/mock-profile.svg new file mode 100644 index 0000000..e7a1302 --- /dev/null +++ b/lens-protocol/core/test/resources/profile-token-uri-images/mock-profile.svg @@ -0,0 +1 @@ +@plant1ghost.eth \ No newline at end of file diff --git a/lens-protocol/core/test/resources/profile-token-uri-images/mock.svg b/lens-protocol/core/test/resources/profile-token-uri-images/mock.svg new file mode 100644 index 0000000..24314c3 --- /dev/null +++ b/lens-protocol/core/test/resources/profile-token-uri-images/mock.svg @@ -0,0 +1 @@ +@plant1ghost.eth \ No newline at end of file diff --git a/lens-protocol/core/test/resources/profile-token-uri-images/other-mock.svg b/lens-protocol/core/test/resources/profile-token-uri-images/other-mock.svg new file mode 100644 index 0000000..e7a1302 --- /dev/null +++ b/lens-protocol/core/test/resources/profile-token-uri-images/other-mock.svg @@ -0,0 +1 @@ +@plant1ghost.eth \ No newline at end of file diff --git a/lens-protocol/core/tsconfig.json b/lens-protocol/core/tsconfig.json new file mode 100644 index 0000000..306b779 --- /dev/null +++ b/lens-protocol/core/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es2019", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "outDir": "dist", + "noImplicitAny": false, + "resolveJsonModule": true + }, + "include": ["./scripts", "./test"], + "files": ["./hardhat.config.ts"] +} diff --git a/lens-protocol/modules/.editorconfig b/lens-protocol/modules/.editorconfig new file mode 100644 index 0000000..1f808de --- /dev/null +++ b/lens-protocol/modules/.editorconfig @@ -0,0 +1,2 @@ +[*] +insert_final_newline = true diff --git a/lens-protocol/modules/.env.example b/lens-protocol/modules/.env.example new file mode 100644 index 0000000..40e51d9 --- /dev/null +++ b/lens-protocol/modules/.env.example @@ -0,0 +1,17 @@ +ETHERSCAN_API_KEY="" +ROPSTEN_URL="" +PRIVATE_KEY="" + +# FOUNDRY: +export MNEMONIC="" +# Can be either mnemonic or private key (but env var must be here empty even if not used) +# Mnemonic is used first, and if it's an empty string - then private key is used +export PRIVATE_KEY="" +export POLYGON_RPC_URL= +export MUMBAI_RPC_URL= +export BLOCK_EXPLORER_KEY= +export MAINNET_EXPLORER_API=https://api.polygonscan.com/api/ +export TESTNET_EXPLORER_API=https://api-testnet.polygonscan.com/api/ + +# Testing fork: keep empty for local testing, mainnet / testnet / sandbox - for testing against forks +export TESTING_FORK= diff --git a/lens-protocol/modules/.eslintignore b/lens-protocol/modules/.eslintignore new file mode 100644 index 0000000..85f5562 --- /dev/null +++ b/lens-protocol/modules/.eslintignore @@ -0,0 +1,4 @@ +node_modules +artifacts +cache +coverage diff --git a/lens-protocol/modules/.eslintrc.js b/lens-protocol/modules/.eslintrc.js new file mode 100644 index 0000000..2ccf0e6 --- /dev/null +++ b/lens-protocol/modules/.eslintrc.js @@ -0,0 +1,44 @@ +module.exports = { + env: { + browser: false, + es2021: true, + mocha: true, + node: true, + }, + plugins: ['@typescript-eslint'], + extends: ['standard', 'plugin:prettier/recommended', 'plugin:node/recommended'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 12, + }, + rules: { + 'node/no-unsupported-features/es-syntax': ['error', { ignores: ['modules'] }], + 'no-unused-vars': 'warn', + 'prefer-const': 'warn', + eqeqeq: 'warn', + camelcase: 'warn', + 'spaced-comment': 'warn', + 'node/no-unpublished-import': 'warn', + 'node/no-unpublished-require': 'warn', + 'eol-last': 'error', + }, + overrides: [ + { + files: ['*.test.ts', '*.spec.ts'], + rules: { + 'no-unused-expressions': 'off', + }, + }, + { + files: ['*.ts'], + rules: { + 'node/no-extraneous-import': 'off', + }, + }, + ], + settings: { + node: { + tryExtensions: ['.js', '.json', '.node', '.ts', '.d.ts'], + }, + }, +}; diff --git a/lens-protocol/modules/.gitmodules b/lens-protocol/modules/.gitmodules new file mode 100644 index 0000000..888d42d --- /dev/null +++ b/lens-protocol/modules/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/lens-protocol/modules/.npmignore b/lens-protocol/modules/.npmignore new file mode 100644 index 0000000..dc03781 --- /dev/null +++ b/lens-protocol/modules/.npmignore @@ -0,0 +1,3 @@ +hardhat.config.ts +scripts +test diff --git a/lens-protocol/modules/.prettierignore b/lens-protocol/modules/.prettierignore new file mode 100644 index 0000000..f268596 --- /dev/null +++ b/lens-protocol/modules/.prettierignore @@ -0,0 +1,5 @@ +node_modules +artifacts +cache +coverage* +gasReporterOutput.json diff --git a/lens-protocol/modules/.prettierrc b/lens-protocol/modules/.prettierrc new file mode 100644 index 0000000..b4c479a --- /dev/null +++ b/lens-protocol/modules/.prettierrc @@ -0,0 +1,17 @@ +{ + "printWidth": 100, + "trailingComma": "es5", + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "overrides": [ + { + "files": "*.sol", + "options": { + "semi": true, + "printWidth": 100, + "tabWidth": 4 + } + } + ] +} diff --git a/lens-protocol/modules/.solhint.json b/lens-protocol/modules/.solhint.json new file mode 100644 index 0000000..6a58166 --- /dev/null +++ b/lens-protocol/modules/.solhint.json @@ -0,0 +1,8 @@ +{ + "extends": "solhint:recommended", + "rules": { + "quotes": "single", + "compiler-version": ["error", "^0.8.0"], + "func-visibility": ["warn", { "ignoreConstructors": true }] + } +} diff --git a/lens-protocol/modules/.solhintignore b/lens-protocol/modules/.solhintignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/lens-protocol/modules/.solhintignore @@ -0,0 +1 @@ +node_modules diff --git a/lens-protocol/modules/.vscode/settings.json b/lens-protocol/modules/.vscode/settings.json new file mode 100644 index 0000000..f7cf4ed --- /dev/null +++ b/lens-protocol/modules/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true, + "solidity.packageDefaultDependenciesContractsDirectory": "src", + "solidity.packageDefaultDependenciesDirectory": "lib" +} diff --git a/lens-protocol/modules/README.md b/lens-protocol/modules/README.md new file mode 100644 index 0000000..026a669 --- /dev/null +++ b/lens-protocol/modules/README.md @@ -0,0 +1,86 @@ +# lens-modules + +Repository for adding Lens Protocol collect, follow and reference modules. + +**To have your module added to Lens Testnet or Mainnet please open a PR and follow the instructions here: #TODO** + +## Installation + +### Special: Foundry installation +follow the instructions in https://www.helpmegeek.com/how-to-integrate-foundry-hardhat-project/ + +especially regarding the lib/ folder + +### Special: preparing .env file for deployment + +#### Mnemonic, private key +1. In a terminal, run `Anvil` +2. Copy the given Mnemonic and one of the private keys into the related variables in .env + +#### RPC urls: +1. Create a (free) account on [Alchemy](https://alchemy.com) +2. In Alchemy, create an app using polygon and mumbai each +3. Click on "view key" and copy the shown url into the RPC variable in .env under "Foundry" + +#### Block explorer: +1. Create a (free) account on [Polygonscan](https://polygonscan.com/) +2. Copy the given API key into the BLOCK_EXPLORER_KEY variable in .env + + +### Continueing original Readme + +1. `npm install` +2. If you also want to use Foundry - follow the Foundry installation instructions [here](https://getfoundry.sh/). + +## Testing + +This repository contains both - Hardhat and Foundry tests. Foundry will be used for all future modules, and existing modules will be migrated to Foundry testing suite. + +### Hardhat + +1. `npm run test` will compile and run the Hardhat tests suite + +### Foundry + +1. `forge test` will compile and run the Foundry tests suite. + +### Foundry tests against forks + +1. Edit `TESTING_FORK` .env variable to be one of `mainnet/testnet/sandbox` and fill the rest of .env (`FOUNDRY` section) +2. If a module is already deployed and its address exists in `addresses.json` - tests will be run against that deployment. If there is no module in json - a new local instance of the module will be deployed. Remove the module key from `addresses.json` if you want to force testing a local module deployment. +3. Run `forge test` to fork the chosen network and test against existing LensHub contracts. + +## Deployment + +1. Make sure to fill in the `.env` using `.env.example` (the `Foundry` section). You can specify either a `MNEMONIC` or a single `PRIVATE_KEY` (make sure to include both variables, even if one of them is an empty string) +2. Run deployment script with a command like `bash script/deploy-module.sh testnet StepwiseCollectModule` from the project root folder (e.g. to deploy `StepwiseCollectModule` on `testnet`). +3. Follow the on-screen instructions to verify if everything is correct and confirm deployment & contract verification. +4. If only the verification is needed of an existing deployed contract - use the `--verify-only` flag followed by ABI-Encoded constructor args. + +## Deployement addresses in `addresses.json` + +The `addresses.json` file in root contains all existing deployed contracts on all of target environments (mainnet/testnet/sandbox) on corresponding chains. +After a succesful module deployment the new address will be added to `addresses.json`, overwriting the existing one (the script will ask for confirmation if you want to redeploy an already existing deployment). + +## Coverage + +1. `npm run coverage` for Hardhat coverage report +2. `forge coverage` for Foundry coverage report + +# Modules + +## Collect modules + +- [**Aave Fee Collect Module**](./contracts/collect/AaveFeeCollectModule.sol): Extend the LimitedFeeCollectModule to deposit all received fees into the Aave Polygon Market (if applicable for the asset) and send the resulting aTokens to the beneficiary. +- [**Auction Collect Module**](./contracts/collect/AuctionCollectModule.sol): This module works by creating an English auction for the underlying publication. After the auction ends, only the auction winner is allowed to collect the publication. +- [**Base Fee Collect Module**](./contracts/collect/base/BaseFeeCollectModule.sol): An abstract base fee collect module contract which can be used to construct flexible fee collect modules using inheritance. +- [**Multirecipient Fee Collect Module**](./contracts/collect/MultirecipientFeeCollectModule.sol): Fee Collect module that allows multiple recipients (up to 5) with different proportions of fees payout. +- [**Simple Fee Collect Module**](./contracts/collect/SimpleFeeCollectModule.sol): A simple fee collect module implementation, as an example of using base fee collect module abstract contract. +- [**Updatable Ownable Fee Collect Module**](./contracts/collect/UpdatableOwnableFeeCollectModule.sol): A fee collect module that, for each publication that uses it, mints an ERC-721 ownership-NFT to its author. Whoever owns the ownership-NFT has the rights to update the parameters required to do a successful collect operation over its underlying publication. + +## Follow modules + +## Reference modules + +- [**Degrees Of Separation Reference Module**](./contracts/reference/DegreesOfSeparationReferenceModule.sol): This reference module allows to set a degree of separation `n`, and then allows to comment/mirror only to profiles that are at most at `n` degrees of separation from the author of the root publication. +- [**Token Gated Reference Module**](./contracts/reference/TokenGatedReferenceModule.sol): A reference module that validates that the user who tries to reference has a required minimum balance of ERC20/ERC721 token. diff --git a/lens-protocol/modules/addresses.json b/lens-protocol/modules/addresses.json new file mode 100644 index 0000000..476afec --- /dev/null +++ b/lens-protocol/modules/addresses.json @@ -0,0 +1,46 @@ +{ + "mainnet": { + "chainId": 137, + "network": "polygon", + "LensHubProxy": "0xDb46d1Dc155634FbC732f92E853b10B288AD5a1d", + "LensHubImplementation": "0x96f1ba24294ffe0dfcd832d8376da4a4645a4cd6", + "ModuleGlobals": "0x3Df697FF746a60CBe9ee8D47555c88CB66f03BB9", + "FreeCollectModule": "0x23b9467334bEb345aAa6fd1545538F3d54436e96", + "PoolAddressesProvider": "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb", + "MultirecipientFeeCollectModule": "0xfa9da21d0a18c7b7de4566481c1e8952371f880a", + "StepwiseCollectModule": "0x210c94877dcfceda8238acd382372278844a54d7", + "ERC4626FeeCollectModule": "0x394fd100b13197787023ef4cf318cde456545db7", + "AaveFeeCollectModule": "0xa94713d0688c8a483c3352635cec4e0ce88d6a29", + "TokenGatedReferenceModule": "0x3d7f4f71a90fe5a9d13fab2716080f2917cf88f3" + }, + "testnet": { + "chainId": 80001, + "network": "mumbai", + "LensHubProxy": "0x60Ae865ee4C725cd04353b5AAb364553f56ceF82", + "LensHubImplementation": "0x1bF5788bEaa62Bc2C2De78523630263312040F77", + "ModuleGlobals": "0x1353aAdfE5FeD85382826757A95DE908bd21C4f9", + "FreeCollectModule": "0x0BE6bD7092ee83D44a6eC1D949626FeE48caB30c", + "PoolAddressesProvider": "0x5343b5bA672Ae99d627A1C87866b8E53F47Db2E6", + "MultirecipientFeeCollectModule": "0x11a9d6779B461147BadD23dC7B87F7aac9b9c8fc", + "StepwiseCollectModule": "0xe690D79708d8b16894Efe0aA04b0EEA2A172D464", + "ERC4626FeeCollectModule": "0x79697402bd2caa19a53d615fb1a30a98e35b84d5", + "AaveFeeCollectModule": "0x912860ed4ed6160c48a52d52fcab5c059d34fe5a", + "TokenGatedReferenceModule": "0xb4ba8dccd35bd3dcc5d58dbb9c7dff9c9268add9", + "PartialCarbonRetirementCollectModule": "0x1316f8Ae936E138B80b59f0Df1C691d1f89eD6C6" + }, + "sandbox": { + "chainId": 80001, + "network": "mumbai", + "LensHubProxy": "0x7582177F9E536aB0b6c721e11f383C326F2Ad1D5", + "LensHubImplementation": "0x1b30F214c192EF4B7F8c9926c47C4161016955DA", + "ModuleGlobals": "0xcbCC5b9611d22d11403373432642Df9Ef7Dd81AD", + "FreeCollectModule": "0x11C45Cbc6fDa2dbe435C0079a2ccF9c4c7051595", + "PoolAddressesProvider": "0x5343b5bA672Ae99d627A1C87866b8E53F47Db2E6", + "MultirecipientFeeCollectModule": "0x4d011e5a19027aDCD5D94E112BC154D8467413d9", + "StepwiseCollectModule": "0xb7B8d677E4e7c27fD70C8eCB6e33Ec1Ec73CD6CA", + "ERC4626FeeCollectModule": "0x31126c602cf88193825a99dcd1d17bf1124b1b4f", + "AaveFeeCollectModule": "0x666e06215747879ee68b3e5a317dcd8411de1897", + "TokenGatedReferenceModule": "0x86d35562ceb9f10d7c2c23c098dfeacb02f53853", + "PartialCarbonRetirementCollectModule": "0x4d011e5a19027aDCD5D94E112BC154D8467413d9" + } +} diff --git a/lens-protocol/modules/contracts/FeeModuleBase.sol b/lens-protocol/modules/contracts/FeeModuleBase.sol new file mode 100644 index 0000000..cd4bc5d --- /dev/null +++ b/lens-protocol/modules/contracts/FeeModuleBase.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {Events} from '@aave/lens-protocol/contracts/libraries/Events.sol'; +import {IModuleGlobals} from '@aave/lens-protocol/contracts/interfaces/IModuleGlobals.sol'; + +/** + * @title FeeModuleBase + * @author Lens Protocol + * + * @notice This is an abstract contract to be inherited from by modules that require basic fee functionality. It + * contains getters for module globals parameters as well as a validation function to check expected data. + */ +abstract contract FeeModuleBase { + uint16 internal constant BPS_MAX = 10000; + + address public immutable MODULE_GLOBALS; + + constructor(address moduleGlobals) { + if (moduleGlobals == address(0)) revert Errors.InitParamsInvalid(); + MODULE_GLOBALS = moduleGlobals; + emit Events.FeeModuleBaseConstructed(moduleGlobals, block.timestamp); + } + + function _currencyWhitelisted(address currency) internal view returns (bool) { + return IModuleGlobals(MODULE_GLOBALS).isCurrencyWhitelisted(currency); + } + + function _treasuryData() internal view returns (address, uint16) { + return IModuleGlobals(MODULE_GLOBALS).getTreasuryData(); + } + + function _validateDataIsExpected( + bytes calldata data, + address currency, + uint256 amount + ) internal pure virtual { + (address decodedCurrency, uint256 decodedAmount) = abi.decode(data, (address, uint256)); + if (decodedAmount != amount || decodedCurrency != currency) + revert Errors.ModuleDataMismatch(); + } +} diff --git a/lens-protocol/modules/contracts/collect/AaveFeeCollectModule.sol b/lens-protocol/modules/contracts/collect/AaveFeeCollectModule.sol new file mode 100644 index 0000000..a9b6069 --- /dev/null +++ b/lens-protocol/modules/contracts/collect/AaveFeeCollectModule.sol @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity 0.8.10; + +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {FeeModuleBase} from '@aave/lens-protocol/contracts/core/modules/FeeModuleBase.sol'; +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; +import {ModuleBase} from '@aave/lens-protocol/contracts/core/modules/ModuleBase.sol'; +import {FollowValidationModuleBase} from '@aave/lens-protocol/contracts/core/modules/FollowValidationModuleBase.sol'; + +import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IPoolDataProvider} from '../interfaces/IPoolDataProvider.sol'; +import {IPool} from '@aave/core-v3/contracts/interfaces/IPool.sol'; + +import {EIP712} from '@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param amount The collecting cost associated with this publication. + * @param currency The currency associated with this publication. + * @param collectLimit The maximum number of collects for this publication. 0 for no limit. + * @param currentCollects The current number of collects for this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly True if only followers of publisher may collect the post. + * @param endTimestamp The end timestamp after which collecting is impossible. 0 for no expiry. + */ +struct ProfilePublicationData { + uint256 amount; + address currency; + uint96 collectLimit; + uint96 currentCollects; + address recipient; + uint16 referralFee; + bool followerOnly; + uint72 endTimestamp; +} + +/** + * @title AaveFeeCollectModule + * @author Lens Protocol + * + * @notice Extend the LimitedFeeCollectModule to deposit all received fees into the Aave Polygon Market (if applicable for the asset) and send the resulting aTokens to the beneficiary. + */ +contract AaveFeeCollectModule is FeeModuleBase, FollowValidationModuleBase, ICollectModule { + using SafeERC20 for IERC20; + + // Pool Address Provider on Polygon for Aave v3 - set in constructor + IPoolAddressesProvider public immutable POOL_ADDRESSES_PROVIDER; + + address public aavePool; + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor( + address hub, + address moduleGlobals, + IPoolAddressesProvider poolAddressesProvider + ) ModuleBase(hub) FeeModuleBase(moduleGlobals) { + POOL_ADDRESSES_PROVIDER = poolAddressesProvider; + + // Retrieve Aave pool address on module deployment + aavePool = POOL_ADDRESSES_PROVIDER.getPool(); + } + + /** + * @dev Anyone can call this function to update Aave v3 addresses. + */ + function updateAavePoolAddress() public { + aavePool = POOL_ADDRESSES_PROVIDER.getPool(); + } + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * + * @param data The arbitrary data parameter, decoded into: + * uint96 collectLimit: The maximum amount of collects. + * uint256 amount: The currency total amount to levy. + * address currency: The currency address, must be internally whitelisted. + * address recipient: The custom recipient address to direct earnings to. + * uint16 referralFee: The referral fee to set. + * bool followerOnly: Whether only followers should be able to collect. + * uint72 endTimestamp: The end timestamp after which collecting is impossible. + * + * @return An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + ( + uint96 collectLimit, + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly, + uint72 endTimestamp + ) = abi.decode(data, (uint96, uint256, address, address, uint16, bool, uint72)); + if ( + !_currencyWhitelisted(currency) || + recipient == address(0) || + referralFee > BPS_MAX || + (endTimestamp < block.timestamp && endTimestamp > 0) + ) revert Errors.InitParamsInvalid(); + + _dataByPublicationByProfile[profileId][pubId].collectLimit = collectLimit; + _dataByPublicationByProfile[profileId][pubId].amount = amount; + _dataByPublicationByProfile[profileId][pubId].currency = currency; + _dataByPublicationByProfile[profileId][pubId].recipient = recipient; + _dataByPublicationByProfile[profileId][pubId].referralFee = referralFee; + _dataByPublicationByProfile[profileId][pubId].followerOnly = followerOnly; + _dataByPublicationByProfile[profileId][pubId].endTimestamp = endTimestamp; + + return data; + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower if followerOnly mode == true + * 2. Ensuring the current timestamp is less than or equal to the collect end timestamp + * 2. Ensuring the collect does not pass the collect limit + * 3. Charging a fee + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + + uint256 endTimestamp = _dataByPublicationByProfile[profileId][pubId].endTimestamp; + uint256 collectLimit = _dataByPublicationByProfile[profileId][pubId].collectLimit; + uint96 currentCollects = _dataByPublicationByProfile[profileId][pubId].currentCollects; + + if (collectLimit != 0 && currentCollects == collectLimit) { + revert Errors.MintLimitExceeded(); + } else if (block.timestamp > endTimestamp && endTimestamp != 0) { + revert Errors.CollectExpired(); + } else { + _dataByPublicationByProfile[profileId][pubId].currentCollects = ++currentCollects; + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + returns (ProfilePublicationData memory) + { + return _dataByPublicationByProfile[profileId][pubId]; + } + + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + + _transferFromAndDepositToAaveIfApplicable( + currency, + collector, + recipient, + amount - treasuryAmount + ); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + function _transferFromAndDepositToAaveIfApplicable( + address currency, + address from, + address beneficiary, + uint256 amount + ) internal { + // First, transfer funds to this contract + IERC20(currency).safeTransferFrom(from, address(this), amount); + IERC20(currency).approve(aavePool, amount); + + // Then, attempt to supply funds in Aave v3, sending aTokens to beneficiary + try IPool(aavePool).supply(currency, amount, beneficiary, 0) {} catch { + // If supply() above fails, send funds directly to beneficiary + IERC20(currency).safeTransfer(beneficiary, amount); + } + } + + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (amount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = amount - treasuryAmount; + + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + // Send referral fee in normal ERC20 tokens + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + _transferFromAndDepositToAaveIfApplicable(currency, collector, recipient, adjustedAmount); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } +} diff --git a/lens-protocol/modules/contracts/collect/AuctionCollectModule.sol b/lens-protocol/modules/contracts/collect/AuctionCollectModule.sol new file mode 100644 index 0000000..2ff6a4c --- /dev/null +++ b/lens-protocol/modules/contracts/collect/AuctionCollectModule.sol @@ -0,0 +1,759 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity 0.8.10; + +import {DataTypes} from '@aave/lens-protocol/contracts/libraries/DataTypes.sol'; +import {EIP712} from '@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol'; +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {FeeModuleBase} from '@aave/lens-protocol/contracts/core/modules/FeeModuleBase.sol'; +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; +import {IERC721Time} from '@aave/lens-protocol/contracts/core/base/IERC721Time.sol'; +import {ILensHub} from '@aave/lens-protocol/contracts/interfaces/ILensHub.sol'; +import {IModuleGlobals} from '@aave/lens-protocol/contracts/interfaces/IModuleGlobals.sol'; +import {ModuleBase} from '@aave/lens-protocol/contracts/core/modules/ModuleBase.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; + +/** + * @notice A struct containing the necessary data to execute collect auctions. + * + * @param availableSinceTimestamp The UNIX timestamp after bids can start to be placed. + * @param startTimestamp The UNIX timestamp of the first bid, i.e. when the auction started. + * @param duration The seconds that the auction will last after the first bid has been placed. + * @param minTimeAfterBid The minimum time, in seconds, that must always remain between last bid's timestamp + * and `endTimestamp`. This restriction could make `endTimestamp` to be re-computed and updated. + * @param endTimestamp The end of auction UNIX timestamp after which bidding is impossible. Computed inside contract. + * @param reservePrice The minimum bid price accepted. + * @param minBidIncrement The minimum amount by which a new bid must overcome the last bid. + * @param winningBid The winning bid amount. + * @param referralFee The percentage of the fee that will be transferred to the referrer in case of having one. + * Measured in basis points, each basis point represents 0.01%. + * @param currency The currency in which the bids are denominated. + * @param recipient The recipient of the auction's winner bid amount. + * @param winner The current auction winner. + * @param onlyFollowers Indicates whether followers are the only allowed to bid, and collect, or not. + * @param collected Indicates whether the publication has been collected or not. + * @param feeProcessed Indicates whether the auction fee was already processed or not. + */ +struct AuctionData { + uint64 availableSinceTimestamp; + uint64 startTimestamp; + uint32 duration; + uint32 minTimeAfterBid; + uint64 endTimestamp; + uint256 reservePrice; + uint256 minBidIncrement; + uint256 winningBid; + uint16 referralFee; + address currency; + address recipient; + address winner; + bool onlyFollowers; + bool collected; + bool feeProcessed; +} + +/** + * @title AuctionCollectModule + * @author Lens Protocol + * + * @notice This module works by creating an English auction for the underlying publication. After the auction ends, only + * the auction winner is allowed to collect the publication. + */ +contract AuctionCollectModule is EIP712, FeeModuleBase, ModuleBase, ICollectModule { + using SafeERC20 for IERC20; + + error OngoingAuction(); + error UnavailableAuction(); + error CollectAlreadyProcessed(); + error FeeAlreadyProcessed(); + error InsufficientBidAmount(); + + event AuctionCreated( + uint256 indexed profileId, + uint256 indexed pubId, + uint64 availableSinceTimestamp, + uint32 duration, + uint32 minTimeAfterBid, + uint256 reservePrice, + uint256 minBidIncrement, + uint16 referralFee, + address currency, + address recipient, + bool onlyFollowers + ); + event BidPlaced( + uint256 indexed profileId, + uint256 indexed pubId, + uint256 referrerProfileId, + uint256 amount, + uint256 followNftTokenId, + address bidder, + uint256 endTimestamp, + uint256 timestamp + ); + event FeeProcessed(uint256 indexed profileId, uint256 indexed pubId, uint256 timestamp); + + mapping(address => uint256) public nonces; + + mapping(uint256 => mapping(uint256 => AuctionData)) internal _auctionDataByPubByProfile; + + /** + * @dev Maps a given bidder's address to its referrer profile ID. Referrer matching publication's profile ID means + * no referral, referrer being zero means that bidder has not bidded yet on this auction. + * The referrer is set through, and only through, the first bidder's bid on each auction. + */ + mapping(uint256 => mapping(uint256 => mapping(address => uint256))) + internal _referrerProfileIdByPubByProfile; + + constructor(address hub, address moduleGlobals) + EIP712('AuctionCollectModule', '1') + ModuleBase(hub) + FeeModuleBase(moduleGlobals) + {} + + /** + * @dev See `AuctionData` struct's natspec in order to understand `data` decoded values. + * + * @inheritdoc ICollectModule + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + ( + uint64 availableSinceTimestamp, + uint32 duration, + uint32 minTimeAfterBid, + uint256 reservePrice, + uint256 minBidIncrement, + uint16 referralFee, + address currency, + address recipient, + bool onlyFollowers + ) = abi.decode( + data, + (uint64, uint32, uint32, uint256, uint256, uint16, address, address, bool) + ); + if ( + duration == 0 || + duration < minTimeAfterBid || + !_currencyWhitelisted(currency) || + referralFee > BPS_MAX + ) { + revert Errors.InitParamsInvalid(); + } + _initAuction( + profileId, + pubId, + availableSinceTimestamp, + duration, + minTimeAfterBid, + reservePrice, + minBidIncrement, + referralFee, + currency, + recipient, + onlyFollowers + ); + return data; + } + + /** + * @notice If the given publication has an auction, this function returns all its information. + * + * @param profileId The token ID of the profile associated with the underlying publication. + * @param pubId The publication ID associated with the underlying publication. + * + * @return The auction data for the given publication. + */ + function getAuctionData(uint256 profileId, uint256 pubId) + external + view + returns (AuctionData memory) + { + return _auctionDataByPubByProfile[profileId][pubId]; + } + + /** + * @notice Processes a collect action for the given publication, this can only be called by the hub. + * + * @dev Process the collect by ensuring: + * 1. Underlying publication's auction has finished. + * 2. Parameters passed matches expected values (collector is the winner, correct referral info & no custom data). + * 3. Publication has not been collected yet. + * This function will also process collect fees if they have not been already processed through `processCollectFee`. + * + * @inheritdoc ICollectModule + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub { + if ( + block.timestamp < _auctionDataByPubByProfile[profileId][pubId].availableSinceTimestamp + ) { + revert UnavailableAuction(); + } + if ( + _auctionDataByPubByProfile[profileId][pubId].startTimestamp == 0 || + block.timestamp <= _auctionDataByPubByProfile[profileId][pubId].endTimestamp + ) { + revert OngoingAuction(); + } + if ( + collector != _auctionDataByPubByProfile[profileId][pubId].winner || + referrerProfileId != _referrerProfileIdByPubByProfile[profileId][pubId][collector] + ) { + revert Errors.ModuleDataMismatch(); + } + if (_auctionDataByPubByProfile[profileId][pubId].collected) { + revert CollectAlreadyProcessed(); + } + if (_auctionDataByPubByProfile[profileId][pubId].onlyFollowers) { + _validateFollow( + profileId, + collector, + abi.decode(data, (uint256)), + _auctionDataByPubByProfile[profileId][pubId].startTimestamp + ); + } else if (data.length > 0) { + // Prevents `LensHub` from emiting `Collected` event with wrong `data` parameter. + revert Errors.ModuleDataMismatch(); + } + _auctionDataByPubByProfile[profileId][pubId].collected = true; + if (!_auctionDataByPubByProfile[profileId][pubId].feeProcessed) { + _processCollectFee(profileId, pubId); + } + } + + /** + * @notice Processes the collect fees using the auction winning bid funds and taking into account referrer and + * treasury fees if necessary. + * + * @dev This function allows anyone to process the collect fees, not needing to wait for `processCollect` to be + * called, as long as the auction has finished, has a winner and the publication has not been collected yet. + * + * @param profileId The token ID of the profile associated with the underlying publication. + * @param pubId The publication ID associated with the underlying publication. + */ + function processCollectFee(uint256 profileId, uint256 pubId) external { + if ( + _auctionDataByPubByProfile[profileId][pubId].duration == 0 || + block.timestamp < _auctionDataByPubByProfile[profileId][pubId].availableSinceTimestamp + ) { + revert UnavailableAuction(); + } + if ( + _auctionDataByPubByProfile[profileId][pubId].startTimestamp == 0 || + block.timestamp <= _auctionDataByPubByProfile[profileId][pubId].endTimestamp + ) { + revert OngoingAuction(); + } + if (_auctionDataByPubByProfile[profileId][pubId].feeProcessed) { + revert FeeAlreadyProcessed(); + } + _processCollectFee(profileId, pubId); + } + + /** + * @notice Places a bid by the given amount on the given publication's auction. If the publication is a mirror, + * the pointed publication auction will be used, setting the mirror's profileId as referrer if it's the first bid + * in the auction. + * Transaction will fail if the bid offered is below auction's current best price. + * + * @dev It will pull the tokens from the bidder to ensure the collect fees can be processed if the bidder ends up + * being the winner after auction ended. If a better bid is placed in the future by a different bidder, funds will + * be automatically transferred to the previous winner. + * + * @param profileId The token ID of the profile associated with the publication, could be a mirror. + * @param pubId The publication ID associated with the publication, could be a mirror. + * @param amount The bid amount to offer. + * @param followNftTokenId The token ID of the Follow NFT to use if the auction is configured as followers-only. + */ + function bid( + uint256 profileId, + uint256 pubId, + uint256 amount, + uint256 followNftTokenId + ) external { + (uint256 rootProfileId, uint256 rootPubId) = _getRootPublication(profileId, pubId); + _bid(rootProfileId, rootPubId, profileId, amount, followNftTokenId, msg.sender); + } + + /** + * @notice Using EIP-712 signatures, places a bid by the given amount on the given publication's auction. + * If the publication is a mirror, the pointed publication auction will be used, setting the mirror's profileId + * as referrer if it's the first bid in the auction. + * Transaction will fail if the bid offered is below auction's current best price. + * + * @dev It will pull the tokens from the bidder to ensure the collect fees can be processed if the bidder ends up + * being the winner after auction ended. If a better bid is placed in the future by a different bidder, funds will + * be automatically transferred to the previous winner. + * + * @param profileId The token ID of the profile associated with the publication, could be a mirror. + * @param pubId The publication ID associated with the publication, could be a mirror. + * @param amount The bid amount to offer. + * @param followNftTokenId The token ID of the Follow NFT to use if the auction is configured as followers-only. + * @param bidder The address of the bidder. + * @param sig The EIP-712 signature for this operation. + */ + function bidWithSig( + uint256 profileId, + uint256 pubId, + uint256 amount, + uint256 followNftTokenId, + address bidder, + DataTypes.EIP712Signature calldata sig + ) external { + _validateBidSignature(profileId, pubId, amount, followNftTokenId, bidder, sig); + (uint256 rootProfileId, uint256 rootPubId) = _getRootPublication(profileId, pubId); + _bid(rootProfileId, rootPubId, profileId, amount, followNftTokenId, bidder); + } + + /** + * @notice Returns the referrer profile in the given publication's auction. + * + * @param profileId The token ID of the profile associated with the underlying publication. + * @param pubId The publication ID associated with the underlying publication. + * @param bidder The address whose referrer profile should be returned. + * + * @return The ID of the referrer profile. Zero means no referral. + */ + function getReferrerProfileIdOf( + uint256 profileId, + uint256 pubId, + address bidder + ) external view returns (uint256) { + uint256 referrerProfileId = _referrerProfileIdByPubByProfile[profileId][pubId][bidder]; + return referrerProfileId == profileId ? 0 : referrerProfileId; + } + + /** + * @notice Initializes the auction struct for the given publication. + * + * @dev Auction initialization logic moved to this function to avoid stack too deep error. + * + * @param profileId The token ID of the profile associated with the underlying publication. + * @param pubId The publication ID associated with the underlying publication. + * @param availableSinceTimestamp The UNIX timestamp after bids can start to be placed. + * @param duration The seconds that the auction will last after the first bid has been placed. + * @param minTimeAfterBid The minimum time, in seconds, that must always remain between last bid's timestamp + * and `endTimestamp`. This restriction could make `endTimestamp` to be re-computed and updated. + * @param reservePrice The minimum bid price accepted. + * @param minBidIncrement The minimum amount by which a new bid must overcome the last bid. + * @param referralFee The percentage of the fee that will be transferred to the referrer in case of having one. + * Measured in basis points, each basis point represents 0.01%. + * @param currency The currency in which the bids are denominated. + * @param recipient The recipient of the auction's winner bid amount. + * @param onlyFollowers Indicates whether followers are the only allowed to bid, and collect, or not. + */ + function _initAuction( + uint256 profileId, + uint256 pubId, + uint64 availableSinceTimestamp, + uint32 duration, + uint32 minTimeAfterBid, + uint256 reservePrice, + uint256 minBidIncrement, + uint16 referralFee, + address currency, + address recipient, + bool onlyFollowers + ) internal { + AuctionData storage auction = _auctionDataByPubByProfile[profileId][pubId]; + auction.availableSinceTimestamp = availableSinceTimestamp; + auction.duration = duration; + auction.minTimeAfterBid = minTimeAfterBid; + auction.reservePrice = reservePrice; + auction.minBidIncrement = minBidIncrement; + auction.referralFee = referralFee; + auction.currency = currency; + auction.recipient = recipient; + auction.onlyFollowers = onlyFollowers; + emit AuctionCreated( + profileId, + pubId, + availableSinceTimestamp, + duration, + minTimeAfterBid, + reservePrice, + minBidIncrement, + referralFee, + currency, + recipient, + onlyFollowers + ); + } + + /** + * @notice Process the fees from the given publication's underlying auction. + * + * @dev It delegates the fee processing to `_processCollectFeeWithoutReferral` or `_processCollectFeeWithReferral` + * depending if has referrer or not. + * + * @param profileId The token ID of the profile associated with the underlying publication. + * @param pubId The publication ID associated with the underlying publication. + */ + function _processCollectFee(uint256 profileId, uint256 pubId) internal { + _auctionDataByPubByProfile[profileId][pubId].feeProcessed = true; + uint256 referrerProfileId = _referrerProfileIdByPubByProfile[profileId][pubId][ + _auctionDataByPubByProfile[profileId][pubId].winner + ]; + if (referrerProfileId == profileId) { + _processCollectFeeWithoutReferral( + _auctionDataByPubByProfile[profileId][pubId].winningBid, + _auctionDataByPubByProfile[profileId][pubId].currency, + _auctionDataByPubByProfile[profileId][pubId].recipient + ); + } else { + _processCollectFeeWithReferral( + _auctionDataByPubByProfile[profileId][pubId].winningBid, + _auctionDataByPubByProfile[profileId][pubId].referralFee, + referrerProfileId, + _auctionDataByPubByProfile[profileId][pubId].currency, + _auctionDataByPubByProfile[profileId][pubId].recipient + ); + } + emit FeeProcessed(profileId, pubId, block.timestamp); + } + + /** + * @notice Process the fees sending the winner amount to the recipient. + * + * @param winnerBid The amount of the winner bid. + * @param currency The currency in which the bids are denominated. + * @param recipient The recipient of the auction's winner bid amount. + */ + function _processCollectFeeWithoutReferral( + uint256 winnerBid, + address currency, + address recipient + ) internal { + (address treasury, uint16 treasuryFee) = _treasuryData(); + uint256 treasuryAmount = (winnerBid * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = winnerBid - treasuryAmount; + IERC20(currency).safeTransfer(recipient, adjustedAmount); + if (treasuryAmount > 0) { + IERC20(currency).safeTransfer(treasury, treasuryAmount); + } + } + + /** + * @notice Process the fees sending the winner amount to the recipient and the corresponding referral fee to the + * owner of the referrer profile. + * + * @param winnerBid The amount of the winner bid. + * @param referralFee The percentage of the fee that will be transferred to the referrer in case of having one. + * Measured in basis points, each basis point represents 0.01%. + * @param referrerProfileId The token ID of the referrer's profile. + * @param currency The currency in which the bids are denominated. + * @param recipient The recipient of the auction's winner bid amount. + */ + function _processCollectFeeWithReferral( + uint256 winnerBid, + uint16 referralFee, + uint256 referrerProfileId, + address currency, + address recipient + ) internal { + (address treasury, uint16 treasuryFee) = _treasuryData(); + uint256 treasuryAmount = (winnerBid * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = winnerBid - treasuryAmount; + if (referralFee > 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + adjustedAmount = adjustedAmount - referralAmount; + IERC20(currency).safeTransfer(IERC721(HUB).ownerOf(referrerProfileId), referralAmount); + } + IERC20(currency).safeTransfer(recipient, adjustedAmount); + if (treasuryAmount > 0) { + IERC20(currency).safeTransfer(treasury, treasuryAmount); + } + } + + /** + * @notice Executes the given bid for the given auction. Each new successful bid transfers back the funds of the + * previous winner and pulls funds from the new winning bidder. + * + * @param profileId The token ID of the profile associated with the underlying publication. + * @param pubId The publication ID associated with the underlying publication. + * @param referrerProfileId The token ID of the referrer's profile. + * @param amount The bid amount to offer. + * @param followNftTokenId The token ID of the Follow NFT to use if the auction is configured as followers-only. + * @param bidder The address of the bidder. + */ + function _bid( + uint256 profileId, + uint256 pubId, + uint256 referrerProfileId, + uint256 amount, + uint256 followNftTokenId, + address bidder + ) internal { + AuctionData memory auction = _auctionDataByPubByProfile[profileId][pubId]; + _validateBid(profileId, amount, followNftTokenId, bidder, auction); + uint256 referrerProfileIdSet = _setReferrerProfileIdIfNotAlreadySet( + profileId, + pubId, + referrerProfileId, + bidder + ); + uint256 endTimestamp = _setNewAuctionStorageStateAfterBid( + profileId, + pubId, + amount, + bidder, + auction + ); + if (auction.winner != address(0)) { + IERC20(auction.currency).safeTransfer(auction.winner, auction.winningBid); + } + IERC20(auction.currency).safeTransferFrom(bidder, address(this), amount); + // `referrerProfileId` and `followNftTokenId` event params are tweaked to provide better semantics for indexers. + emit BidPlaced( + profileId, + pubId, + referrerProfileIdSet == profileId ? 0 : referrerProfileIdSet, + amount, + auction.onlyFollowers ? followNftTokenId : 0, + bidder, + endTimestamp, + block.timestamp + ); + } + + /** + * @notice Valides if the given bid is valid for the given auction. + * + * @param profileId The token ID of the profile associated with the underlying publication. + * @param amount The bid amount to offer. + * @param followNftTokenId The token ID of the Follow NFT to use if the auction is configured as followers-only. + * @param bidder The address of the bidder. + * @param auction The data of the auction where the bid is being placed. + */ + function _validateBid( + uint256 profileId, + uint256 amount, + uint256 followNftTokenId, + address bidder, + AuctionData memory auction + ) internal view { + if ( + auction.duration == 0 || + block.timestamp < auction.availableSinceTimestamp || + (auction.startTimestamp > 0 && block.timestamp > auction.endTimestamp) + ) { + revert UnavailableAuction(); + } + _validateBidAmount(auction, amount); + if (auction.onlyFollowers) { + _validateFollow( + profileId, + bidder, + followNftTokenId, + auction.startTimestamp == 0 ? block.timestamp : auction.startTimestamp + ); + } + } + + /** + * @notice Updates the state of the auction data after a successful bid. + * + * @param profileId The token ID of the profile associated with the underlying publication. + * @param pubId The publication ID associated with the underlying publication. + * @param newWinningBid The amount of the new winning bid. + * @param newWinner The new winning bidder. + * @param prevAuctionState The state of the auction data before the bid, which will be overrided. + * + * @return A UNIX timestamp representing the `endTimestamp` of the new auction state. + */ + function _setNewAuctionStorageStateAfterBid( + uint256 profileId, + uint256 pubId, + uint256 newWinningBid, + address newWinner, + AuctionData memory prevAuctionState + ) internal returns (uint256) { + AuctionData storage nextAuctionState = _auctionDataByPubByProfile[profileId][pubId]; + nextAuctionState.winner = newWinner; + nextAuctionState.winningBid = newWinningBid; + uint256 endTimestamp = prevAuctionState.endTimestamp; + if (prevAuctionState.winner == address(0)) { + endTimestamp = block.timestamp + prevAuctionState.duration; + nextAuctionState.endTimestamp = uint64(endTimestamp); + nextAuctionState.startTimestamp = uint64(block.timestamp); + } else if (endTimestamp - block.timestamp < prevAuctionState.minTimeAfterBid) { + endTimestamp = block.timestamp + prevAuctionState.minTimeAfterBid; + nextAuctionState.endTimestamp = uint64(endTimestamp); + } + return endTimestamp; + } + + /** + * @notice Sets the the given `referrerProfileId` if it is the first bid of the bidder, or returns the previously + * set otherwise. + * + * @param profileId The token ID of the profile associated with the underlying publication. + * @param pubId The publication ID associated with the underlying publication. + * @param referrerProfileId The token ID of the referrer's profile. + * @param bidder The address of the bidder whose referrer profile id is being set. + * + * @return The token ID of the referrer profile for the given bidder. Being equals to `profileId` means no referrer. + */ + function _setReferrerProfileIdIfNotAlreadySet( + uint256 profileId, + uint256 pubId, + uint256 referrerProfileId, + address bidder + ) internal returns (uint256) { + uint256 referrerProfileIdSet = _referrerProfileIdByPubByProfile[profileId][pubId][bidder]; + if (referrerProfileIdSet == 0) { + _referrerProfileIdByPubByProfile[profileId][pubId][bidder] = referrerProfileId; + referrerProfileIdSet = referrerProfileId; + } + return referrerProfileIdSet; + } + + /** + * @notice Checks if the given bid amount is valid for the given auction. + * + * @param auction The auction where the bid amount validation should be performed. + * @param amount The bid amount to validate. + */ + function _validateBidAmount(AuctionData memory auction, uint256 amount) internal pure { + bool auctionStartsWithCurrentBid = auction.winner == address(0); + if ( + (auctionStartsWithCurrentBid && amount < auction.reservePrice) || + (!auctionStartsWithCurrentBid && + (amount <= auction.winningBid || + (auction.minBidIncrement > 0 && + amount - auction.winningBid < auction.minBidIncrement))) + ) { + revert InsufficientBidAmount(); + } + } + + /** + * @notice Checks the given Follow NFT is owned by the given follower, is part of the given followed profile's + * follow NFT collection and was minted before the given deadline. + * + * @param profileId The token ID of the profile associated with the publication. + * @param follower The address performing the follow operation. + * @param followNftTokenId The token ID of the Follow NFT to use. + * @param maxValidFollowTimestamp The maximum timestamp for which Follow NFTs should have been minted before to be + * valid for this scenario. + */ + function _validateFollow( + uint256 profileId, + address follower, + uint256 followNftTokenId, + uint256 maxValidFollowTimestamp + ) internal view { + address followNFT = ILensHub(HUB).getFollowNFT(profileId); + if ( + followNFT == address(0) || + IERC721(followNFT).ownerOf(followNftTokenId) != follower || + IERC721Time(followNFT).mintTimestampOf(followNftTokenId) > maxValidFollowTimestamp + ) { + revert Errors.FollowInvalid(); + } + } + + /** + * @notice Returns the pointed publication if the passed one is a mirror, otherwise just returns the passed one. + * + * @param profileId The token ID of the profile associated with the publication, could be a mirror. + * @param pubId The publication ID associated with the publication, could be a mirror. + */ + function _getRootPublication(uint256 profileId, uint256 pubId) + internal + view + returns (uint256, uint256) + { + DataTypes.PublicationStruct memory publication = ILensHub(HUB).getPub(profileId, pubId); + if (publication.collectModule != address(0)) { + return (profileId, pubId); + } else { + if (publication.profileIdPointed == 0) { + revert Errors.PublicationDoesNotExist(); + } + return (publication.profileIdPointed, publication.pubIdPointed); + } + } + + /** + * @notice Checks if the signature for the `bidWithSig` function is valid according EIP-712 standard. + * + * @param profileId The token ID of the profile associated with the publication, could be a mirror. + * @param pubId The publication ID associated with the publication, could be a mirror. + * @param amount The bid amount to offer. + * @param followNftTokenId The token ID of the Follow NFT to use if the auction is configured as followers-only. + * @param bidder The address of the bidder. + * @param sig The EIP-712 signature to validate. + */ + function _validateBidSignature( + uint256 profileId, + uint256 pubId, + uint256 amount, + uint256 followNftTokenId, + address bidder, + DataTypes.EIP712Signature calldata sig + ) internal { + unchecked { + _validateRecoveredAddress( + _calculateDigest( + abi.encode( + keccak256( + 'BidWithSig(uint256 profileId,uint256 pubId,uint256 amount,uint256 followNftTokenId,uint256 nonce,uint256 deadline)' + ), + profileId, + pubId, + amount, + followNftTokenId, + nonces[bidder]++, + sig.deadline + ) + ), + bidder, + sig + ); + } + } + + /** + * @notice Checks the recovered address is the expected signer for the given signature. + * + * @param digest The expected signed data. + * @param expectedAddress The address of the expected signer. + * @param sig The signature. + */ + function _validateRecoveredAddress( + bytes32 digest, + address expectedAddress, + DataTypes.EIP712Signature calldata sig + ) internal view { + if (sig.deadline < block.timestamp) { + revert Errors.SignatureExpired(); + } + address recoveredAddress = ecrecover(digest, sig.v, sig.r, sig.s); + if (recoveredAddress == address(0) || recoveredAddress != expectedAddress) { + revert Errors.SignatureInvalid(); + } + } + + /** + * @notice Calculates the digest for the given bytes according EIP-712 standard. + * + * @param message The message, as bytes, to calculate the digest from. + */ + function _calculateDigest(bytes memory message) internal view returns (bytes32) { + return keccak256(abi.encodePacked('\x19\x01', _domainSeparatorV4(), keccak256(message))); + } +} diff --git a/lens-protocol/modules/contracts/collect/CarbonRecipientFeeCollectModule.sol b/lens-protocol/modules/contracts/collect/CarbonRecipientFeeCollectModule.sol new file mode 100644 index 0000000..cdda716 --- /dev/null +++ b/lens-protocol/modules/contracts/collect/CarbonRecipientFeeCollectModule.sol @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import '@openzeppelin/contracts/utils/Strings.sol'; +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {BaseFeeCollectModule} from './base/BaseFeeCollectModule.sol'; +import {CarbonRetireBase} from './base/CarbonRetireBase.sol'; +import {BaseProfilePublicationData, BaseFeeCollectModuleInitData} from './base/IBaseFeeCollectModule.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; + +enum RecipientType { + ERC20, + CARBON +} + +struct RecipientData { + RecipientType recipientType; + address recipient; // applies for ERC20 + address poolToken; // applies for CARBON + uint16 split; // fraction of BPS_MAX (10 000) +} + +/** + * @notice A struct containing the necessary data to initialize MultirecipientFeeCollectModule. + * + * @param amount The collecting cost associated with this publication. Cannot be 0. + * @param collectLimit The maximum number of collects for this publication. 0 for no limit. + * @param currency The currency associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly True if only followers of publisher may collect the post. + * @param endTimestamp The end timestamp after which collecting is impossible. 0 for no expiry. + * @param recipients Array of RecipientData items to split collect fees across multiple recipients. + */ +struct MultirecipientFeeCollectModuleInitData { + uint160 amount; + uint96 collectLimit; + address currency; + uint16 referralFee; + bool followerOnly; + uint72 endTimestamp; + RecipientData[] recipients; +} + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param amount The collecting cost associated with this publication. Cannot be 0. + * @param collectLimit The maximum number of collects for this publication. 0 for no limit. + * @param currency The currency associated with this publication. + * @param currentCollects The current number of collects for this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly True if only followers of publisher may collect the post. + * @param endTimestamp The end timestamp after which collecting is impossible. 0 for no expiry. + * @param recipients Array of RecipientData items to split collect fees across multiple recipients. + */ +struct MultirecipientFeeCollectProfilePublicationData { + uint160 amount; + uint96 collectLimit; + address currency; + uint96 currentCollects; + uint16 referralFee; + bool followerOnly; + uint72 endTimestamp; + RecipientData[] recipients; +} + +error TooManyRecipients(); +error InvalidRecipientSplits(); +error RecipientSplitCannotBeZero(); + +/** + * @title CarbonRecipientCollectModule + * @author Lens Protocol + * + * @notice Alternative implementation of carbob retirements, borrowed from MultirecipientFeeCollectModule, but recipients get divided into two groups that are processed differently. + * This is a simple Lens CollectModule implementation, allowing customization of time to collect, number of collects, + * splitting collect fee across multiple recipients, and whether only followers can collect. + * It is charging a fee for collect and distributing it among (one or up to five) Receivers, Referral, Treasury. + */ +contract CarbonRecipientFeeCollectModule is BaseFeeCollectModule, CarbonRetireBase { + using SafeERC20 for IERC20; + + uint256 internal constant MAX_RECIPIENTS = 5; + + mapping(uint256 => mapping(uint256 => RecipientData[])) + internal _recipientsByPublicationByProfile; + + constructor( + address hub, + address moduleGlobals, + address retirementHelper + ) BaseFeeCollectModule(hub, moduleGlobals) CarbonRetireBase(retirementHelper) {} + + /** + * @inheritdoc ICollectModule + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + MultirecipientFeeCollectModuleInitData memory initData = abi.decode( + data, + (MultirecipientFeeCollectModuleInitData) + ); + + BaseFeeCollectModuleInitData memory baseInitData = BaseFeeCollectModuleInitData({ + amount: initData.amount, + collectLimit: initData.collectLimit, + currency: initData.currency, + referralFee: initData.referralFee, + followerOnly: initData.followerOnly, + endTimestamp: initData.endTimestamp, + recipient: address(0) + }); + + // Zero amount for collect doesn't make sense here (in a module with 5 recipients) + // For this better use FreeCollect module instead + if (baseInitData.amount == 0) revert Errors.InitParamsInvalid(); + _validateBaseInitData(baseInitData); + _validateAndStoreRecipients(initData, profileId, pubId); + _storeBasePublicationCollectParameters(profileId, pubId, baseInitData); + return data; + } + + /** + * @dev Validates the recipients array and stores them to (a separate from Base) storage. + * + * @param initData MultirecipientFeeCollectModuleInitData + * @param profileId The profile ID who is publishing the publication. + * @param pubId The associated publication's LensHub publication ID. + */ + function _validateAndStoreRecipients( + MultirecipientFeeCollectModuleInitData memory initData, + uint256 profileId, + uint256 pubId + ) internal { + uint256 len = initData.recipients.length; + + // Check number of recipients is supported + if (len > MAX_RECIPIENTS) revert TooManyRecipients(); + if (len == 0) revert Errors.InitParamsInvalid(); + + // Skip loop check if only 1 recipient in the array + if (len == 1) { + if (initData.recipients[0].recipientType == RecipientType.CARBON) { + checkRetirementSwapFeasibility( + initData.currency, + initData.recipients[0].poolToken, + initData.amount * initData.recipients[0].split + ); + if (initData.recipients[0].split != BPS_MAX) revert InvalidRecipientSplits(); + } else if (initData.recipients[0].recipientType == RecipientType.ERC20) { + if (initData.recipients[0].recipient == address(0)) + revert Errors.InitParamsInvalid(); + if (initData.recipients[0].split != BPS_MAX) revert InvalidRecipientSplits(); + } else revert Errors.InitParamsInvalid(); + + // If single recipient passes check above, store and return + _recipientsByPublicationByProfile[profileId][pubId].push(initData.recipients[0]); + } else { + // Check recipient splits sum to 10 000 BPS (100%) + uint256 totalSplits; + for (uint256 i = 0; i < len; ) { + if (initData.recipients[i].recipientType == RecipientType.CARBON) { + checkRetirementSwapFeasibility( + initData.currency, + initData.recipients[i].poolToken, + initData.amount * initData.recipients[i].split + ); + if (initData.recipients[i].split == 0) revert InvalidRecipientSplits(); + } else if (initData.recipients[i].recipientType == RecipientType.ERC20) { + if (initData.recipients[i].recipient == address(0)) + revert Errors.InitParamsInvalid(); + if (initData.recipients[i].split == 0) revert InvalidRecipientSplits(); + } else revert Errors.InitParamsInvalid(); + + totalSplits += initData.recipients[i].split; + + // Store each recipient while looping - avoids extra gas costs in successful cases + _recipientsByPublicationByProfile[profileId][pubId].push(initData.recipients[i]); + + unchecked { + ++i; + } + } + + if (totalSplits != BPS_MAX) revert InvalidRecipientSplits(); + } + } + + /** + * @dev Transfers the fee to multiple recipients. + * + * @inheritdoc BaseFeeCollectModule + */ + function _transferToRecipients( + address currency, + address collector, + uint256 profileId, + uint256 pubId, + uint256 amount + ) internal override { + RecipientData[] memory recipients = _recipientsByPublicationByProfile[profileId][pubId]; + uint256 len = recipients.length; + + // If only 1 recipient, transfer full amount and skip split calculations + if (len == 1) { + if (recipients[0].recipientType == RecipientType.CARBON) { + string memory retiringEntityString = string( + abi.encodePacked( + 'Collecting Lens profile: ', + Strings.toString(profileId), + ', by collector:', + Strings.toHexString(collector) + ) + ); + string memory beneficiaryString = string( + abi.encodePacked( + 'Lens publication: ', + Strings.toString(pubId), + ', by publisher: ', + Strings.toHexString(recipients[0].recipient) + ) + ); + string memory retirementMessage = string( + abi.encodePacked( + 'Lens Protocol carbon retirement for collect of publication: ', + Strings.toString(pubId) + ) + ); + + _retireCarbon( + collector, + recipients[0].recipient, //TODO: recipient not checked for CARBON, but should be publisher or can be removed + currency, + recipients[0].poolToken, + amount, + retiringEntityString, + beneficiaryString, + retirementMessage + ); + } else if (recipients[0].recipientType == RecipientType.ERC20) { + IERC20(currency).safeTransferFrom(collector, recipients[0].recipient, amount); + } + } else { + uint256 splitAmount; + for (uint256 i = 0; i < len; ) { + splitAmount = (amount * recipients[i].split) / BPS_MAX; + if (splitAmount != 0) { + if (recipients[i].recipientType == RecipientType.CARBON) { + string memory retiringEntityString = string( + abi.encodePacked( + 'Collecting Lens profile: ', + Strings.toString(profileId), + ', by collector:', + Strings.toHexString(collector) + ) + ); + string memory beneficiaryString = string( + abi.encodePacked( + 'Lens publication: ', + Strings.toString(pubId), + ', by publisher: ', + Strings.toHexString(recipients[i].recipient) + ) + ); + string memory retirementMessage = string( + abi.encodePacked( + 'Lens Protocol carbon retirement for collect of publication: ', + Strings.toString(pubId) + ) + ); + + _retireCarbon( + collector, + recipients[i].recipient, //TODO: recipient not checked for CARBON, but should be publisher or can be removed + currency, + recipients[i].poolToken, + splitAmount, + retiringEntityString, + beneficiaryString, + retirementMessage + ); + } else if (recipients[i].recipientType == RecipientType.ERC20) { + IERC20(currency).safeTransferFrom( + collector, + recipients[i].recipient, + splitAmount + ); + } + } + + unchecked { + ++i; + } + } + } + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return The BaseProfilePublicationData struct mapped to that publication. + */ + function getPublicationData( + uint256 profileId, + uint256 pubId + ) external view returns (MultirecipientFeeCollectProfilePublicationData memory) { + BaseProfilePublicationData memory baseData = getBasePublicationData(profileId, pubId); + RecipientData[] memory recipients = _recipientsByPublicationByProfile[profileId][pubId]; + + return + MultirecipientFeeCollectProfilePublicationData({ + amount: baseData.amount, + collectLimit: baseData.collectLimit, + currency: baseData.currency, + currentCollects: baseData.currentCollects, + referralFee: baseData.referralFee, + followerOnly: baseData.followerOnly, + endTimestamp: baseData.endTimestamp, + recipients: recipients + }); + } +} diff --git a/lens-protocol/modules/contracts/collect/ERC4626FeeCollectModule.sol b/lens-protocol/modules/contracts/collect/ERC4626FeeCollectModule.sol new file mode 100644 index 0000000..c39c9ae --- /dev/null +++ b/lens-protocol/modules/contracts/collect/ERC4626FeeCollectModule.sol @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {FeeModuleBase} from '@aave/lens-protocol/contracts/core/modules/FeeModuleBase.sol'; +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; +import {ModuleBase} from '@aave/lens-protocol/contracts/core/modules/ModuleBase.sol'; +import {FollowValidationModuleBase} from '@aave/lens-protocol/contracts/core/modules/FollowValidationModuleBase.sol'; + +import {IERC4626} from '@openzeppelin/contracts/interfaces/IERC4626.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param collectLimit The maximum number of collects for this publication. + * @param currentCollects The current number of collects for this publication. + * @param amount The collecting cost associated with this publication. + * @param vault The ERC4626 compatible vault in which fees are deposited. + * @param currency The currency associated with this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param endTimestamp The end timestamp after which collecting is impossible. + */ +struct ProfilePublicationData { + uint256 amount; + address vault; // ERC4626 Vault in which fees are deposited + uint96 collectLimit; + address currency; + uint96 currentCollects; + address recipient; + uint16 referralFee; + bool followerOnly; + uint72 endTimestamp; +} + +/** + * @title ERC4626FeeCollectModule + * @author Lens Protocol + * + * @notice Extend the LimitedFeeCollectModule to deposit all received fees into an ERC-4626 compatible vault and send the resulting shares to the beneficiary. + */ +contract ERC4626FeeCollectModule is FeeModuleBase, FollowValidationModuleBase, ICollectModule { + using SafeERC20 for IERC20; + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor(address hub, address moduleGlobals) ModuleBase(hub) FeeModuleBase(moduleGlobals) {} + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * + * @param data The arbitrary data parameter, decoded into: + * uint96 collectLimit: The maximum amount of collects. 0 for no limit. + * uint256 amount: The currency total amount to levy. + * address vault: The ERC4626 compatible vault in which fees are deposited. + * address recipient: The custom recipient address to direct earnings to. + * uint16 referralFee: The referral fee to set. + * bool followerOnly: Whether only followers should be able to collect. + * uint72 endTimestamp: The end timestamp after which collecting is impossible. 0 for no expiry. + * + * @return An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + ( + uint96 collectLimit, + uint256 amount, + address vault, + address recipient, + uint16 referralFee, + bool followerOnly, + uint72 endTimestamp + ) = abi.decode(data, (uint96, uint256, address, address, uint16, bool, uint72)); + + // Get fee currency from vault's asset instead of publication params + address currency = IERC4626(vault).asset(); + + if ( + !_currencyWhitelisted(currency) || + vault == address(0) || + recipient == address(0) || + referralFee > BPS_MAX || + (endTimestamp < block.timestamp && endTimestamp > 0) + ) revert Errors.InitParamsInvalid(); + + _dataByPublicationByProfile[profileId][pubId].collectLimit = collectLimit; + _dataByPublicationByProfile[profileId][pubId].amount = amount; + _dataByPublicationByProfile[profileId][pubId].vault = vault; + _dataByPublicationByProfile[profileId][pubId].currency = currency; + _dataByPublicationByProfile[profileId][pubId].recipient = recipient; + _dataByPublicationByProfile[profileId][pubId].referralFee = referralFee; + _dataByPublicationByProfile[profileId][pubId].followerOnly = followerOnly; + _dataByPublicationByProfile[profileId][pubId].endTimestamp = endTimestamp; + + return data; + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower if followerOnly mode == true + * 2. Ensuring the current timestamp is less than or equal to the collect end timestamp + * 2. Ensuring the collect does not pass the collect limit + * 3. Charging a fee + * + * @inheritdoc ICollectModule + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + + uint256 endTimestamp = _dataByPublicationByProfile[profileId][pubId].endTimestamp; + uint256 collectLimit = _dataByPublicationByProfile[profileId][pubId].collectLimit; + uint96 currentCollects = _dataByPublicationByProfile[profileId][pubId].currentCollects; + + if (collectLimit != 0 && currentCollects >= collectLimit) { + revert Errors.MintLimitExceeded(); + } else if (block.timestamp > endTimestamp && endTimestamp != 0) { + revert Errors.CollectExpired(); + } else { + _dataByPublicationByProfile[profileId][pubId].currentCollects = ++currentCollects; + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + returns (ProfilePublicationData memory) + { + return _dataByPublicationByProfile[profileId][pubId]; + } + + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + address vault = _dataByPublicationByProfile[profileId][pubId].vault; + + (address treasury, uint16 treasuryFee) = _treasuryData(); + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + + _transferFromAndDepositInVaultIfApplicable( + currency, + vault, + collector, + recipient, + amount - treasuryAmount + ); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (amount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = amount - treasuryAmount; + + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + // Send referral fee in normal ERC20 tokens + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + _transferFromAndDepositInVaultIfApplicable( + currency, + _dataByPublicationByProfile[profileId][pubId].vault, + collector, + recipient, + adjustedAmount + ); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + function _transferFromAndDepositInVaultIfApplicable( + address currency, + address vault, + address from, + address beneficiary, + uint256 amount + ) internal { + // First, transfer funds to this contract + IERC20(currency).safeTransferFrom(from, address(this), amount); + IERC20(currency).approve(vault, amount); + + // Then, attempt to deposit funds in vault, sending shares to beneficiary + try IERC4626(vault).deposit(amount, beneficiary) {} catch { + // If deposit() above fails, send funds directly to beneficiary + IERC20(currency).safeTransfer(beneficiary, amount); + } + } +} diff --git a/lens-protocol/modules/contracts/collect/MultirecipientFeeCollectModule.sol b/lens-protocol/modules/contracts/collect/MultirecipientFeeCollectModule.sol new file mode 100644 index 0000000..753c2a5 --- /dev/null +++ b/lens-protocol/modules/contracts/collect/MultirecipientFeeCollectModule.sol @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {BaseFeeCollectModule} from './base/BaseFeeCollectModule.sol'; +import {BaseProfilePublicationData, BaseFeeCollectModuleInitData} from './base/IBaseFeeCollectModule.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; + +struct RecipientData { + address recipient; + uint16 split; // fraction of BPS_MAX (10 000) +} + +/** + * @notice A struct containing the necessary data to initialize MultirecipientFeeCollectModule. + * + * @param amount The collecting cost associated with this publication. Cannot be 0. + * @param collectLimit The maximum number of collects for this publication. 0 for no limit. + * @param currency The currency associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly True if only followers of publisher may collect the post. + * @param endTimestamp The end timestamp after which collecting is impossible. 0 for no expiry. + * @param recipients Array of RecipientData items to split collect fees across multiple recipients. + */ +struct MultirecipientFeeCollectModuleInitData { + uint160 amount; + uint96 collectLimit; + address currency; + uint16 referralFee; + bool followerOnly; + uint72 endTimestamp; + RecipientData[] recipients; +} + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param amount The collecting cost associated with this publication. Cannot be 0. + * @param collectLimit The maximum number of collects for this publication. 0 for no limit. + * @param currency The currency associated with this publication. + * @param currentCollects The current number of collects for this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly True if only followers of publisher may collect the post. + * @param endTimestamp The end timestamp after which collecting is impossible. 0 for no expiry. + * @param recipients Array of RecipientData items to split collect fees across multiple recipients. + */ +struct MultirecipientFeeCollectProfilePublicationData { + uint160 amount; + uint96 collectLimit; + address currency; + uint96 currentCollects; + uint16 referralFee; + bool followerOnly; + uint72 endTimestamp; + RecipientData[] recipients; +} + +error TooManyRecipients(); +error InvalidRecipientSplits(); +error RecipientSplitCannotBeZero(); + +/** + * @title MultirecipientCollectModule + * @author Lens Protocol + * + * @notice This is a simple Lens CollectModule implementation, allowing customization of time to collect, number of collects, + * splitting collect fee across multiple recipients, and whether only followers can collect. + * It is charging a fee for collect and distributing it among (one or up to five) Receivers, Referral, Treasury. + */ +contract MultirecipientFeeCollectModule is BaseFeeCollectModule { + using SafeERC20 for IERC20; + + uint256 internal constant MAX_RECIPIENTS = 5; + + mapping(uint256 => mapping(uint256 => RecipientData[])) + internal _recipientsByPublicationByProfile; + + constructor(address hub, address moduleGlobals) BaseFeeCollectModule(hub, moduleGlobals) {} + + /** + * @inheritdoc ICollectModule + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + MultirecipientFeeCollectModuleInitData memory initData = abi.decode( + data, + (MultirecipientFeeCollectModuleInitData) + ); + + BaseFeeCollectModuleInitData memory baseInitData = BaseFeeCollectModuleInitData({ + amount: initData.amount, + collectLimit: initData.collectLimit, + currency: initData.currency, + referralFee: initData.referralFee, + followerOnly: initData.followerOnly, + endTimestamp: initData.endTimestamp, + recipient: address(0) + }); + + // Zero amount for collect doesn't make sense here (in a module with 5 recipients) + // For this better use FreeCollect module instead + if (baseInitData.amount == 0) revert Errors.InitParamsInvalid(); + _validateBaseInitData(baseInitData); + _validateAndStoreRecipients(initData.recipients, profileId, pubId); + _storeBasePublicationCollectParameters(profileId, pubId, baseInitData); + return data; + } + + /** + * @dev Validates the recipients array and stores them to (a separate from Base) storage. + * + * @param recipients An array of recipients + * @param profileId The profile ID who is publishing the publication. + * @param pubId The associated publication's LensHub publication ID. + */ + function _validateAndStoreRecipients( + RecipientData[] memory recipients, + uint256 profileId, + uint256 pubId + ) internal { + uint256 len = recipients.length; + + // Check number of recipients is supported + if (len > MAX_RECIPIENTS) revert TooManyRecipients(); + if (len == 0) revert Errors.InitParamsInvalid(); + + // Skip loop check if only 1 recipient in the array + if (len == 1) { + if (recipients[0].recipient == address(0)) revert Errors.InitParamsInvalid(); + if (recipients[0].split != BPS_MAX) revert InvalidRecipientSplits(); + + // If single recipient passes check above, store and return + _recipientsByPublicationByProfile[profileId][pubId].push(recipients[0]); + } else { + // Check recipient splits sum to 10 000 BPS (100%) + uint256 totalSplits; + for (uint256 i = 0; i < len; ) { + if (recipients[i].recipient == address(0)) revert Errors.InitParamsInvalid(); + if (recipients[i].split == 0) revert RecipientSplitCannotBeZero(); + totalSplits += recipients[i].split; + + // Store each recipient while looping - avoids extra gas costs in successful cases + _recipientsByPublicationByProfile[profileId][pubId].push(recipients[i]); + + unchecked { + ++i; + } + } + + if (totalSplits != BPS_MAX) revert InvalidRecipientSplits(); + } + } + + /** + * @dev Transfers the fee to multiple recipients. + * + * @inheritdoc BaseFeeCollectModule + */ + function _transferToRecipients( + address currency, + address collector, + uint256 profileId, + uint256 pubId, + uint256 amount + ) internal override { + RecipientData[] memory recipients = _recipientsByPublicationByProfile[profileId][pubId]; + uint256 len = recipients.length; + + // If only 1 recipient, transfer full amount and skip split calculations + if (len == 1) { + IERC20(currency).safeTransferFrom(collector, recipients[0].recipient, amount); + } else { + uint256 splitAmount; + for (uint256 i = 0; i < len; ) { + splitAmount = (amount * recipients[i].split) / BPS_MAX; + if (splitAmount != 0) + IERC20(currency).safeTransferFrom( + collector, + recipients[i].recipient, + splitAmount + ); + + unchecked { + ++i; + } + } + } + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return The BaseProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + returns (MultirecipientFeeCollectProfilePublicationData memory) + { + BaseProfilePublicationData memory baseData = getBasePublicationData(profileId, pubId); + RecipientData[] memory recipients = _recipientsByPublicationByProfile[profileId][pubId]; + + return + MultirecipientFeeCollectProfilePublicationData({ + amount: baseData.amount, + collectLimit: baseData.collectLimit, + currency: baseData.currency, + currentCollects: baseData.currentCollects, + referralFee: baseData.referralFee, + followerOnly: baseData.followerOnly, + endTimestamp: baseData.endTimestamp, + recipients: recipients + }); + } +} diff --git a/lens-protocol/modules/contracts/collect/PartialCarbonRetirementCollectModule.sol b/lens-protocol/modules/contracts/collect/PartialCarbonRetirementCollectModule.sol new file mode 100644 index 0000000..3b2cf12 --- /dev/null +++ b/lens-protocol/modules/contracts/collect/PartialCarbonRetirementCollectModule.sol @@ -0,0 +1,464 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +import '@openzeppelin/contracts/utils/Strings.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {FeeModuleBase} from '@aave/lens-protocol/contracts/core/modules/FeeModuleBase.sol'; +import {ModuleBase} from '@aave/lens-protocol/contracts/core/modules/ModuleBase.sol'; +import {FollowValidationModuleBase} from '@aave/lens-protocol/contracts/core/modules/FollowValidationModuleBase.sol'; + +import {CarbonRetireBase} from './base/CarbonRetireBase.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * @param amount The collecting cost associated with this publication. 0 for free collect. + * @param currency The currency associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly Whether only followers should be able to collect. + * @param recipient The recipient address associated with this publication. + * @param endTimestamp The end timestamp after which collecting is impossible. + * @param currentCollects The current number of collects for this publication. + * @param collectLimit The maximum number of collects for this publication (0 for unlimited) + * @param poolToken The carbon token to be used for carbon retirement. + * @param retirementSplit Fraction (BPS) of amount that goes into carbon retirement. + */ +struct ProfilePublicationData { + uint160 amount; + address currency; + uint16 referralFee; + bool followerOnly; + address recipient; + uint40 endTimestamp; + uint64 currentCollects; + uint64 collectLimit; + address poolToken; + uint16 retirementSplit; +} + +/** + * @notice A struct containing the necessary data to initialize Stepwise Collect Module. + * @param amount The collecting cost associated with this publication. 0 for free collect. + * @param collectLimit The maximum number of collects for this publication (0 for unlimited) + * @param currency The currency associated with this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly Whether only followers should be able to collect. + * @param endTimestamp The end timestamp after which collecting is impossible. + * @param poolToken The carbon token to be used for carbon retirement. + * @param retirementSplit Fraction (BPS) of amount that goes into carbon retirement. + */ +struct PartialCarbonRetirementCollectModuleInitData { + uint160 amount; + uint64 collectLimit; + address currency; + address recipient; + uint16 referralFee; + bool followerOnly; + uint40 endTimestamp; + address poolToken; + uint16 retirementSplit; +} + +/** + * @title PartialCarbonRetirementCollectModule + * @author Lens Protocol + * + * @notice This module sends a chosen fraction of the collect fee to perform carbon retirement. + * The Publisher can choose the carbon pool token and the fraction of the total collect fee for the retirement. + * The collector only needs to hold the collect fee currency, no carbon tokens. Swap happens through the retirement aggregator during collect. + * + * Treasury fee and referralFee are calculated only on the amount that the publisher/recipient gets, ignoring the retirement amount. + * + * If retirement is not possible during collect, the collect process still takes place. + * In this case, the recipient/publisher gets the full amount and a notice in the transaction that they should perform the retirement manually at a later point. + * In this case, treasury fee and referralFee are calculated on the total amount that the recipient/publisher gets. + * + */ +contract PartialCarbonRetirementCollectModule is + CarbonRetireBase, + FeeModuleBase, + FollowValidationModuleBase, + ICollectModule +{ + using SafeERC20 for IERC20; + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor( + address hub, + address moduleGlobals, + address klimaInfinity + ) FeeModuleBase(moduleGlobals) ModuleBase(hub) CarbonRetireBase(klimaInfinity) {} + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * @param data The arbitrary data parameter, decoded into: + * recipientAmount: The collecting cost associated with this publication. 0 for free collect. + * collectLimit: The maximum number of collects for this publication. 0 for no limit. + * currency: The currency associated with this publication. + * referralFee: The referral fee associated with this publication. + * followerOnly: True if only followers of publisher may collect the post. + * endTimestamp: The end timestamp after which collecting is impossible. 0 for no expiry. + * recipient: Recipient of collect fees. + * pooltToken: Carbon token for retierement + * retirementSplit: Fration of amount to go to retirement + * + * @return An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external virtual onlyHub returns (bytes memory) { + PartialCarbonRetirementCollectModuleInitData memory initData = abi.decode( + data, + (PartialCarbonRetirementCollectModuleInitData) + ); + { + uint256 retirementAmount = (initData.retirementSplit * initData.amount) / BPS_MAX; + if ( + !checkRetirementSwapFeasibility( + initData.currency, + initData.poolToken, + retirementAmount + ) || + !_currencyWhitelisted(initData.currency) || + // TODO: should this be included? Removed, because 100% retirement doesn't need recipient + //initData.recipient == address(0) || + initData.referralFee > BPS_MAX || + initData.retirementSplit > BPS_MAX || + (initData.endTimestamp != 0 && initData.endTimestamp < block.timestamp) + ) revert Errors.InitParamsInvalid(); + } + + _dataByPublicationByProfile[profileId][pubId] = ProfilePublicationData({ + amount: initData.amount, + currency: initData.currency, + referralFee: initData.referralFee, + followerOnly: initData.followerOnly, + recipient: initData.recipient, + endTimestamp: initData.endTimestamp, + currentCollects: 0, + collectLimit: initData.collectLimit, + poolToken: initData.poolToken, + retirementSplit: initData.retirementSplit + }); + return data; + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower + * 2. Ensuring the current timestamp is less than or equal to the collect end timestamp + * 3. Ensuring the collect does not pass the collect limit + * 4. Charging a fee + * 5. Performing the retirement and collect + * + * @inheritdoc ICollectModule + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + uint256 endTimestamp = _dataByPublicationByProfile[profileId][pubId].endTimestamp; + if (endTimestamp != 0 && block.timestamp > endTimestamp) revert Errors.CollectExpired(); + + if ( + _dataByPublicationByProfile[profileId][pubId].collectLimit != 0 && + _dataByPublicationByProfile[profileId][pubId].currentCollects >= + _dataByPublicationByProfile[profileId][pubId].collectLimit + ) { + revert Errors.MintLimitExceeded(); + } else { + unchecked { + ++_dataByPublicationByProfile[profileId][pubId].currentCollects; + } + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + } + + /** + * @dev Internal processing of a collect: + * 1. Calculation of fees + * 2. Validation that fees are what collector expected + * 3. Transfer of fees to recipient and treasury + * + * @param collector The address that will collect the post. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Arbitrary data __passed from the collector!__ to be decoded. + */ + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal virtual { + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + uint256 retirementAmount = (_dataByPublicationByProfile[profileId][pubId].retirementSplit * + _dataByPublicationByProfile[profileId][pubId].amount) / BPS_MAX; + + // TODO: Learn what this does. Guess: checks that calldata of collect equals init data of publication + _validateDataIsExpected( + data, + currency, + _dataByPublicationByProfile[profileId][pubId].amount + ); + + // Try retirement and return recipientAmount. + uint256 recipientAmount = _performCarbonRetirement( + collector, + _dataByPublicationByProfile[profileId][pubId].recipient, + pubId, + profileId, + currency, + _dataByPublicationByProfile[profileId][pubId].poolToken, + retirementAmount + ); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + uint256 treasuryAmount = (recipientAmount * treasuryFee) / BPS_MAX; + + // Send amount after treasury cut, to all recipients + _transferToRecipients( + currency, + collector, + profileId, + pubId, + recipientAmount - treasuryAmount + ); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @dev Internal processing of a collect: + * 1. Calculation of fees + * 2. Validation that fees are what collector expected + * 3. Transfer of fees to recipient(-s) and treasury + * + * @param collector The address that will collect the post. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Arbitrary data __passed from the collector!__ to be decoded. + */ + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal virtual { + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + uint256 retirementAmount = (_dataByPublicationByProfile[profileId][pubId].retirementSplit * + _dataByPublicationByProfile[profileId][pubId].amount) / BPS_MAX; + + // TODO: Learn what this does. Guess: checks that calldata of collect equals init data of publication + _validateDataIsExpected( + data, + currency, + _dataByPublicationByProfile[profileId][pubId].amount + ); + + // Try retirement and return recipientAmount. + uint256 recipientAmount = _performCarbonRetirement( + collector, + _dataByPublicationByProfile[profileId][pubId].recipient, + pubId, + profileId, + currency, + _dataByPublicationByProfile[profileId][pubId].poolToken, + retirementAmount + ); + + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (recipientAmount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = recipientAmount - treasuryAmount; + adjustedAmount = _transferToReferrals( + currency, + referrerProfileId, + collector, + profileId, + pubId, + adjustedAmount + ); + + _transferToRecipients(currency, collector, profileId, pubId, adjustedAmount); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @dev Wrapper for carbon retirement: + * Creates retirement messages + * Performs (attempts) retirement + * Returns remaining recipient amount + * + * @param collector The address that will collect the post. + * @param recipient The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param profileId Arbitrary data __passed from the collector!__ to be decoded. + * @param currency Currency of the collect + * @param poolToken Carbon pool token for retirement + * @param retirementAmount Amount of currency to be retired + */ + function _performCarbonRetirement( + address collector, + address recipient, + uint256 pubId, + uint256 profileId, + address currency, + address poolToken, + uint256 retirementAmount + ) internal returns (uint256 recipientAmount) { + // Perform retirement if checkSwapFeasibility works. + if (checkRetirementSwapFeasibility(currency, poolToken, retirementAmount)) { + string memory retiringEntityString = string( + abi.encodePacked( + 'Collecting Lens profile: ', + Strings.toString(profileId), + ', by collector:', + Strings.toHexString(collector) + ) + ); + string memory beneficiaryString = string( + abi.encodePacked( + 'Lens publication: ', + Strings.toString(pubId), + ', by publisher: ', + Strings.toHexString(recipient) + ) + ); + string memory retirementMessage = string( + abi.encodePacked( + 'Lens Protocol carbon retirement for collect of publication: ', + Strings.toString(pubId) + ) + ); + _retireCarbon( + collector, + recipient, + currency, + poolToken, + retirementAmount, + retiringEntityString, + beneficiaryString, + retirementMessage + ); + + recipientAmount = + _dataByPublicationByProfile[profileId][pubId].amount - + retirementAmount; + } else { + // TODO: Up to debate. This fallback sends everything to recipient with treasury fee for everything. + recipientAmount = _dataByPublicationByProfile[profileId][pubId].amount; + // TODO: Add event or something to signal to recipient that they should perform + // a manual retirement of all failed retirements at a later time + } + } + + /** + * @dev Transfers the fee to recipient + * + * Override this to add additional functionality (e.g. multiple recipients) + * + * @param currency Currency of the transaction + * @param collector The address that collects the post (and pays the fee). + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param amount Amount to transfer to recipient(-s) + */ + function _transferToRecipients( + address currency, + address collector, + uint256 profileId, + uint256 pubId, + uint256 amount + ) internal virtual { + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + if (amount > 0) { + IERC20(currency).safeTransferFrom(collector, recipient, amount); + } + } + + /** + * @dev Transfers the part of fee to referral(-s) + * + * Override this to add additional functionality (e.g. multiple referrals) + * + * @param currency Currency of the transaction + * @param referrerProfileId The address of the referral. + * @param collector The address that collects the post (and pays the fee). + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param adjustedAmount Amount of the fee after subtracting the Treasury part. + */ + function _transferToReferrals( + address currency, + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + uint256 adjustedAmount + ) internal virtual returns (uint256) { + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + if (referralAmount > 0) { + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + // Send referral fee in normal ERC20 tokens + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + } + return adjustedAmount; + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData( + uint256 profileId, + uint256 pubId + ) external view virtual returns (ProfilePublicationData memory) { + return _dataByPublicationByProfile[profileId][pubId]; + } +} diff --git a/lens-protocol/modules/contracts/collect/SimpleFeeCollectModule.sol b/lens-protocol/modules/contracts/collect/SimpleFeeCollectModule.sol new file mode 100644 index 0000000..864c64f --- /dev/null +++ b/lens-protocol/modules/contracts/collect/SimpleFeeCollectModule.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +import {BaseFeeCollectModule} from './base/BaseFeeCollectModule.sol'; +import {BaseFeeCollectModuleInitData, BaseProfilePublicationData} from './base/IBaseFeeCollectModule.sol'; + +/** + * @title SimpleFeeCollectModule + * @author Lens Protocol + * + * @notice This is a simple Lens CollectModule implementation, allowing customization of time to collect, + * number of collects and whether only followers can collect. + * + * You can build your own collect modules by inheriting from BaseFeeCollectModule and adding your + * functionality along with getPublicationData function. + */ +contract SimpleFeeCollectModule is BaseFeeCollectModule { + constructor(address hub, address moduleGlobals) BaseFeeCollectModule(hub, moduleGlobals) {} + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * @param data The arbitrary data parameter, decoded into: + * amount: The collecting cost associated with this publication. 0 for free collect. + * collectLimit: The maximum number of collects for this publication. 0 for no limit. + * currency: The currency associated with this publication. + * referralFee: The referral fee associated with this publication. + * followerOnly: True if only followers of publisher may collect the post. + * endTimestamp: The end timestamp after which collecting is impossible. 0 for no expiry. + * recipient: Recipient of collect fees. + * + * @return An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external virtual onlyHub returns (bytes memory) { + BaseFeeCollectModuleInitData memory baseInitData = abi.decode( + data, + (BaseFeeCollectModuleInitData) + ); + _validateBaseInitData(baseInitData); + _storeBasePublicationCollectParameters(profileId, pubId, baseInitData); + return data; + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return The BaseProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + virtual + returns (BaseProfilePublicationData memory) + { + return getBasePublicationData(profileId, pubId); + } +} diff --git a/lens-protocol/modules/contracts/collect/StepwiseCollectModule.sol b/lens-protocol/modules/contracts/collect/StepwiseCollectModule.sol new file mode 100644 index 0000000..060b2b1 --- /dev/null +++ b/lens-protocol/modules/contracts/collect/StepwiseCollectModule.sol @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {FeeModuleBase} from '../FeeModuleBase.sol'; +import {ModuleBase} from '@aave/lens-protocol/contracts/core/modules/ModuleBase.sol'; +import {FollowValidationModuleBase} from '@aave/lens-protocol/contracts/core/modules/FollowValidationModuleBase.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * @notice a, b, c are coefficients of a standard quadratic equation (ax^2+bx+c) curve. + * @dev Variable sizes are optimized to fit in 3 slots. + * @param currency The currency associated with this publication. + * @param a The a multiplier of x^2 in quadratic equation (how quadratic is the curve) + * @param referralFee The referral fee associated with this publication. + * @param followerOnly Whether only followers should be able to collect. + * @param recipient The recipient address associated with this publication. + * @param b The b multiplier of x in quadratic equation (if a==0, how steep is the line) + * @param endTimestamp The end timestamp after which collecting is impossible. + * @param c The c constant in quadratic equation (aka start price) + * @param currentCollects The current number of collects for this publication. + * @param collectLimit The maximum number of collects for this publication (0 for unlimited) + */ +struct ProfilePublicationData { + address currency; // 1st slot + uint72 a; + uint16 referralFee; + bool followerOnly; + address recipient; // 2nd slot + uint56 b; + uint40 endTimestamp; + uint128 c; // 3rd slot + uint64 currentCollects; + uint64 collectLimit; +} + +/** + * @notice A struct containing the necessary data to initialize Stepwise Collect Module. + * + * @param collectLimit The maximum number of collects for this publication (0 for unlimited) + * @param currency The currency associated with this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly Whether only followers should be able to collect. + * @param endTimestamp The end timestamp after which collecting is impossible. + * @param a The a multiplier of x^2 in quadratic equation (how quadratic is the curve) (9 decimals) + * @param b The b multiplier of x in quadratic equation (if a==0, how steep is the line) (9 decimals) + * @param c The c constant in quadratic equation (aka start price) (18 decimals) + */ +struct StepwiseCollectModuleInitData { + uint64 collectLimit; + address currency; + address recipient; + uint16 referralFee; + bool followerOnly; + uint40 endTimestamp; + uint72 a; + uint56 b; + uint128 c; +} + +/** + * @title StepwiseCollectModule + * @author Lens Protocol + * + * @notice This is a simple Lens CollectModule implementation, inheriting from the ICollectModule interface and + * the FeeCollectModuleBase abstract contract. + * + * This module works by allowing limited collects for a publication within the allotted time with a changing fee. + * + * The fee is calculated based on a simple quadratic equation: + * Fee = a*x^2 + b*x + c, + * (where x is how many collects were already performed) + * + * a=b=0 makes it a constant-fee collect + * a=0 makes it a linear-growing fee collect + */ +contract StepwiseCollectModule is FeeModuleBase, FollowValidationModuleBase, ICollectModule { + using SafeERC20 for IERC20; + + // As there is hard storage optimisation of a,b,c parameters, the following decimals convention is assumed for fixed-point calculations: + uint256 public constant A_DECIMALS = 1e9; // leaves 30 bits for fractional part, 42 bits for integer part + uint256 public constant B_DECIMALS = 1e9; // leaves 30 bits for fractional part, 26 bits for integer part + // For C the decimals will be equal to currency decimals + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor(address hub, address moduleGlobals) FeeModuleBase(moduleGlobals) ModuleBase(hub) {} + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * + * @param profileId The profile ID of the publication to initialize this module for. + * @param pubId The publication ID to initialize this module for. + * @param data The arbitrary data parameter, decoded into: StepwiseCollectModuleInitData struct + * @return bytes An abi encoded bytes parameter, containing a struct with module initialization data. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + StepwiseCollectModuleInitData memory initData = abi.decode( + data, + (StepwiseCollectModuleInitData) + ); + { + if ( + !_currencyWhitelisted(initData.currency) || + initData.recipient == address(0) || + initData.referralFee > BPS_MAX || + (initData.endTimestamp != 0 && initData.endTimestamp < block.timestamp) + ) revert Errors.InitParamsInvalid(); + } + _dataByPublicationByProfile[profileId][pubId] = ProfilePublicationData({ + currency: initData.currency, + a: initData.a, + referralFee: initData.referralFee, + followerOnly: initData.followerOnly, + recipient: initData.recipient, + b: initData.b, + endTimestamp: initData.endTimestamp, + c: initData.c, + currentCollects: 0, + collectLimit: initData.collectLimit + }); + return data; + } + + /** + * @dev Processes a collect by: + * 1. Ensuring the collector is a follower + * 2. Ensuring the current timestamp is less than or equal to the collect end timestamp + * 3. Ensuring the collect does not pass the collect limit + * 4. Charging a fee + * + * @inheritdoc ICollectModule + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + uint256 endTimestamp = _dataByPublicationByProfile[profileId][pubId].endTimestamp; + if (endTimestamp != 0 && block.timestamp > endTimestamp) revert Errors.CollectExpired(); + + if ( + _dataByPublicationByProfile[profileId][pubId].collectLimit != 0 && + _dataByPublicationByProfile[profileId][pubId].currentCollects >= + _dataByPublicationByProfile[profileId][pubId].collectLimit + ) { + revert Errors.MintLimitExceeded(); + } else { + unchecked { + ++_dataByPublicationByProfile[profileId][pubId].currentCollects; + } + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return ProfilePublicationData The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + returns (ProfilePublicationData memory) + { + return _dataByPublicationByProfile[profileId][pubId]; + } + + // TODO: Decide if we need a view function at all + /** + * @notice Estimates the amount next collect will cost for a given publication. + * @notice Subject to front-running, thus some slippage should be added. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return fee Collect fee + */ + function previewFee(uint256 profileId, uint256 pubId) public view returns (uint256) { + ProfilePublicationData memory data = _dataByPublicationByProfile[profileId][pubId]; + data.currentCollects++; + return _calculateFee(data); + } + + /** + * @dev Calculates the collect fee using quadratic formula. + * + * @param data ProfilePublicationData from storage containing the publication parameters. + * + * @return fee Collect fee. + */ + function _calculateFee(ProfilePublicationData memory data) internal pure returns (uint256) { + // Because we already incremented the current collects in storage - we need to adjust it here. + // This is done to allow the first collect price to be equal to c parameter (better UX) + uint256 collects = data.currentCollects - 1; + if (data.a == 0) return (uint256(data.b) * collects) / B_DECIMALS + data.c; + return + ((uint256(data.a) * collects * collects) / A_DECIMALS) + + ((uint256(data.b) * collects) / B_DECIMALS) + + data.c; + } + + /** + * @dev Calculates and processes the collect action. + * + * @param collector The address that collects the publicaton. + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * @param data Abi encoded bytes parameter, containing currency address and fee amount + */ + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _calculateFee(_dataByPublicationByProfile[profileId][pubId]); + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + if (amount > 0) { + (address treasury, uint16 treasuryFee) = _treasuryData(); + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = amount - treasuryAmount; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @dev Calculates and processes the collect action with referral. + * + * @param referrerProfileId The profile receiving referral fees. + * @param collector The address that collects the publicaton. + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * @param data Abi encoded bytes parameter, containing currency address and fee amount + */ + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _calculateFee(_dataByPublicationByProfile[profileId][pubId]); + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + if (amount > 0) { + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (amount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = amount - treasuryAmount; + + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + + if (referralAmount > 0) { + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + } + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @dev Validates if the desired data provided (currency and maximum amount) corresponds to actual values of the tx. + * + * @param data Abi encoded bytes parameter, containing currency address and fee amount + * @param currency Currency of the fee. + * @param amount Fee amount. + */ + function _validateDataIsExpected( + bytes calldata data, + address currency, + uint256 amount + ) internal pure override { + (address decodedCurrency, uint256 decodedMaxAmount) = abi.decode(data, (address, uint256)); + if (amount > decodedMaxAmount || decodedCurrency != currency) + revert Errors.ModuleDataMismatch(); + } +} diff --git a/lens-protocol/modules/contracts/collect/UpdatableOwnableFeeCollectModule.sol b/lens-protocol/modules/contracts/collect/UpdatableOwnableFeeCollectModule.sol new file mode 100644 index 0000000..3e9f66a --- /dev/null +++ b/lens-protocol/modules/contracts/collect/UpdatableOwnableFeeCollectModule.sol @@ -0,0 +1,508 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +import {Base64} from '@openzeppelin/contracts/utils/Base64.sol'; +import {DataTypes} from '@aave/lens-protocol/contracts/libraries/DataTypes.sol'; +import {EIP712} from '@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol'; +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {FeeModuleBase} from '@aave/lens-protocol/contracts/core/modules/FeeModuleBase.sol'; +import {FollowValidationModuleBase} from '@aave/lens-protocol/contracts/core/modules/FollowValidationModuleBase.sol'; +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/interfaces/IERC721.sol'; +import {ILensHub} from '@aave/lens-protocol/contracts/interfaces/ILensHub.sol'; +import {LensNFTBase} from '@aave/lens-protocol/contracts/core/base/LensNFTBase.sol'; +import {ModuleBase} from '@aave/lens-protocol/contracts/core/modules/ModuleBase.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param ownershipTokenId The token ID of the ownership NFT asociated with the publication. + * @param amount The collecting cost associated with this publication. + * @param currency The currency associated with this publication. + * @param recipient The recipient address associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly Whether only followers should be able to collect. + */ +struct ProfilePublicationData { + uint256 ownershipTokenId; + uint256 amount; + address currency; + address recipient; + uint16 referralFee; + bool followerOnly; +} + +/** + * @notice A struct containing the publication composite identifier. + * + * @param profileId The token ID of the profile associated with the publication. + * @param pubId The publication ID associated with the publication. + */ +struct Publication { + uint256 profileId; + uint256 pubId; +} + +/** + * @title UpdatableOwnableFeeCollectModule + * @author Lens Protocol + * + * @notice A fee collect module that, for each publication that uses it, mints an ERC-721 ownership-NFT to its author. + * Whoever owns the ownership-NFT has the rights to update the parameters required to do a successful collect operation + * over its underlying publication. + * + */ +contract UpdatableOwnableFeeCollectModule is + EIP712, + FeeModuleBase, + FollowValidationModuleBase, + LensNFTBase, + ICollectModule +{ + using SafeERC20 for IERC20; + + error InvalidParameters(); + error OnlyOwner(); + + event ModuleParametersUpdated( + uint256 indexed profileId, + uint256 indexed pubId, + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly + ); + + uint256 internal _tokenIdCounter; + + mapping(uint256 => mapping(uint256 => ProfilePublicationData)) + internal _dataByPublicationByProfile; + + mapping(uint256 => Publication) internal _publicationByTokenId; + + constructor(address hub, address moduleGlobals) + EIP712('UpdatableOwnableFeeCollectModule', '1') + FeeModuleBase(moduleGlobals) + ModuleBase(hub) + {} + + /** + * @dev Returns the Uniform Resource Identifier (URI) for the given token. + * + * @param tokenId The ID of the token whose URI is being queried. + * + * @return string The corresponding token URI. + */ + function tokenURI(uint256 tokenId) public view override returns (string memory) { + if (!_exists(tokenId)) { + revert Errors.TokenDoesNotExist(); + } + string memory pubIdString = string( + abi.encodePacked( + Strings.toString(_publicationByTokenId[tokenId].profileId), + '-', + Strings.toString(_publicationByTokenId[tokenId].pubId) + ) + ); + return + string( + abi.encodePacked( + 'data:application/json;base64,', + Base64.encode( + abi.encodePacked( + '{ "name": "Ownership of Lens Publication #', + pubIdString, + '","description": "Owning this NFT allows the owner to change the collect parameters of the #', + pubIdString, + ' publication.", "image": "ipfs://bafkreifclgvhtotpoquwoo7enjof6xfqjbthukddkxagtykjfnc3kh6khm" }' + ) + ) + ) + ); + } + + /** + * @notice This collect module levies a fee on collects and supports referrals. Thus, we need to decode data. + * + * @param profileId The token ID of the profile of the publisher, passed by the hub. + * @param pubId The publication ID of the newly created publication, passed by the hub. + * @param data The arbitrary data parameter, decoded into: + * uint256 amount: The currency total amount to levy. + * address currency: The currency address, must be internally whitelisted. + * address recipient: The custom recipient address to direct earnings to. + * uint16 referralFee: The referral fee to set. + * bool followerOnly: Whether only followers should be able to collect. + * + * @return bytes An abi encoded bytes parameter, which is the same as the passed data parameter. + */ + function initializePublicationCollectModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + ( + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly + ) = abi.decode(data, (uint256, address, address, uint16, bool)); + if (!_currencyWhitelisted(currency) || referralFee > BPS_MAX) { + revert Errors.InitParamsInvalid(); + } + + unchecked { + uint256 tokenId = ++_tokenIdCounter; + _mint(IERC721(HUB).ownerOf(profileId), tokenId); + _publicationByTokenId[tokenId] = Publication(profileId, pubId); + _dataByPublicationByProfile[profileId][pubId].ownershipTokenId = tokenId; + } + _dataByPublicationByProfile[profileId][pubId].amount = amount; + _dataByPublicationByProfile[profileId][pubId].currency = currency; + _dataByPublicationByProfile[profileId][pubId].recipient = recipient; + _dataByPublicationByProfile[profileId][pubId].referralFee = referralFee; + _dataByPublicationByProfile[profileId][pubId].followerOnly = followerOnly; + + return data; + } + + /** + * @notice Process the collect operation over the given publication, in this case by charging a fee. + * + * @dev Only callable by the LensHub contract. It delegates the fee processing to + * `_processCollectFeeWithoutReferral` or `_processCollectFeeWithReferral` depending if has referrer or not. + * + * @param referrerProfileId The LensHub profile token ID of the referrer's profile (only different in case of mirrors). + * @param collector The collector address. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Custom data that must contain the expected fee currency and amount encoded. + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external virtual override onlyHub { + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) { + _checkFollowValidity(profileId, collector); + } + if (_dataByPublicationByProfile[profileId][pubId].amount > 0) { + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + } + + /** + * @notice Allows the owner of the ownership-NFT corresponding to the given publication to update the parameters + * required to do a successful collect operation. + * + * @param profileId The token ID of the profile associated with the publication. + * @param pubId The publication ID associated with the publication. + * @param amount The amount of fee charged for each collect. + * @param currency The currency in which the amount is charged. + * @param recipient The address that will receive the collect fees. + * @param referralFee The percentage of the fee that will be transferred to the referrer in case of having one. + * Measured in basis points, each basis point represents 0.01%. + * @param followerOnly A boolean indicating whether followers are the only allowed to collect or not. + */ + function updateModuleParameters( + uint256 profileId, + uint256 pubId, + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly + ) external virtual { + _updateModuleParameters( + profileId, + pubId, + amount, + currency, + recipient, + referralFee, + followerOnly, + msg.sender + ); + } + + /** + * @notice Allows the owner of the ownership-NFT corresponding to the given publication to update the parameters + * required to do a successful collect operation. + * + * @param profileId The token ID of the profile associated with the publication. + * @param pubId The publication ID associated with the publication. + * @param amount The amount of fee charged for each collect. + * @param currency The currency in which the amount is charged. + * @param recipient The address that will receive the collect fees. + * @param referralFee The percentage of the fee that will be transferred to the referrer in case of having one. + * Measured in basis points, each basis point represents 0.01%. + * @param followerOnly A boolean indicating whether followers are the only allowed to collect or not. + * @param operator The address that is executing this parameter update. Should match the recovered signer. + * @param sig The EIP-712 signature for this operation. + */ + function updateModuleParametersWithSig( + uint256 profileId, + uint256 pubId, + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly, + address operator, + DataTypes.EIP712Signature calldata sig + ) external virtual { + _validateUpdateModuleParametersSignature( + profileId, + pubId, + amount, + currency, + recipient, + referralFee, + followerOnly, + operator, + sig + ); + _updateModuleParameters( + profileId, + pubId, + amount, + currency, + recipient, + referralFee, + followerOnly, + operator + ); + } + + /** + * @notice Returns the publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return ProfilePublicationData The ProfilePublicationData struct mapped to that publication. + */ + function getPublicationData(uint256 profileId, uint256 pubId) + external + view + returns (ProfilePublicationData memory) + { + return _dataByPublicationByProfile[profileId][pubId]; + } + + /** + * @notice Returns the underlying publication corresponding to the given token ID. + * + * @param tokenId The ID of the token whose underlying publication is being queried. + * + * @return PublicationStruct The PublicationStruct of the given publication. + */ + function getPublicationByTokenId(uint256 tokenId) + public + view + returns (DataTypes.PublicationStruct memory) + { + if (!_exists(tokenId)) { + revert Errors.TokenDoesNotExist(); + } + return + ILensHub(HUB).getPub( + _publicationByTokenId[tokenId].profileId, + _publicationByTokenId[tokenId].pubId + ); + } + + /** + * @notice Process the collect fee without referral. + * + * @param collector The collector address. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Custom data that must contain the expected fee currency and amount encoded. + */ + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = amount - treasuryAmount; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @notice Process the collect fee with referral. + * + * @param referrerProfileId The LensHub profile token ID of the referrer's profile. + * @param collector The collector address. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Custom data that must contain the expected fee currency and amount encoded. + */ + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal { + uint256 amount = _dataByPublicationByProfile[profileId][pubId].amount; + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (amount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = amount - treasuryAmount; + + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount); + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @notice Internal function to abstract the logic regarding the parameter updating. + * + * @param profileId The token ID of the profile associated with the publication. + * @param pubId The publication ID associated with the publication. + * @param amount The amount of fee charged for each collect. + * @param currency The currency in which the amount is charged. + * @param recipient The address that will receive the collect fees. + * @param referralFee The percentage of the fee that will be transferred to the referrer in case of having one. + * Measured in basis points, each basis point represents 0.01%. + * @param followerOnly A boolean indicating whether followers are the only allowed to collect or not. + * @param operator The address that is executing this parameter update. + */ + function _updateModuleParameters( + uint256 profileId, + uint256 pubId, + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly, + address operator + ) internal { + if (ownerOf(_dataByPublicationByProfile[profileId][pubId].ownershipTokenId) != operator) { + revert OnlyOwner(); + } + if (!_currencyWhitelisted(currency) || referralFee > BPS_MAX) { + revert InvalidParameters(); + } + _dataByPublicationByProfile[profileId][pubId].amount = amount; + _dataByPublicationByProfile[profileId][pubId].currency = currency; + _dataByPublicationByProfile[profileId][pubId].recipient = recipient; + _dataByPublicationByProfile[profileId][pubId].referralFee = referralFee; + _dataByPublicationByProfile[profileId][pubId].followerOnly = followerOnly; + emit ModuleParametersUpdated( + profileId, + pubId, + amount, + currency, + recipient, + referralFee, + followerOnly + ); + } + + /** + * @notice Checks if the signature for the `updateModuleParametersWithSig` function is valid according EIP-712. + * + * @param profileId The token ID of the profile associated with the publication. + * @param pubId The publication ID associated with the publication. + * @param amount The amount of fee charged for each collect. + * @param currency The currency in which the amount is charged. + * @param recipient The address that will receive the collect fees. + * @param referralFee The percentage of the fee that will be transferred to the referrer in case of having one. + * Measured in basis points, each basis point represents 0.01%. + * @param followerOnly A boolean indicating whether followers are the only allowed to collect or not. + * @param operator The address that is executing this parameter update. Should match the recovered signer. + * @param sig The EIP-712 signature for this operation. + */ + function _validateUpdateModuleParametersSignature( + uint256 profileId, + uint256 pubId, + uint256 amount, + address currency, + address recipient, + uint16 referralFee, + bool followerOnly, + address operator, + DataTypes.EIP712Signature calldata sig + ) internal { + unchecked { + _validateRecoveredAddress( + _calculateDigest( + abi.encode( + keccak256( + 'UpdateModuleParametersWithSig(uint256 profileId,uint256 pubId,uint256 amount,address currency,address recipient,uint16 referralFee,bool followerOnly,uint256 nonce,uint256 deadline)' + ), + profileId, + pubId, + amount, + currency, + recipient, + referralFee, + followerOnly, + sigNonces[operator]++, + sig.deadline + ) + ), + operator, + sig + ); + } + } + + /** + * @notice Calculates the digest for the given bytes according EIP-712 standard. + * + * @param message The message, as bytes, to calculate the digest from. + */ + function _calculateDigest(bytes memory message) internal view returns (bytes32) { + return keccak256(abi.encodePacked('\x19\x01', _domainSeparatorV4(), keccak256(message))); + } +} diff --git a/lens-protocol/modules/contracts/collect/base/BaseFeeCollectModule.sol b/lens-protocol/modules/contracts/collect/base/BaseFeeCollectModule.sol new file mode 100644 index 0000000..a144b9a --- /dev/null +++ b/lens-protocol/modules/contracts/collect/base/BaseFeeCollectModule.sol @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {FeeModuleBase} from '@aave/lens-protocol/contracts/core/modules/FeeModuleBase.sol'; +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; +import {ModuleBase} from '@aave/lens-protocol/contracts/core/modules/ModuleBase.sol'; +import {FollowValidationModuleBase} from '@aave/lens-protocol/contracts/core/modules/FollowValidationModuleBase.sol'; + +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; + +import {BaseFeeCollectModuleInitData, BaseProfilePublicationData, IBaseFeeCollectModule} from './IBaseFeeCollectModule.sol'; + +/** + * @title BaseFeeCollectModule + * @author Lens Protocol + * + * @notice This is an base Lens CollectModule implementation, allowing customization of time to collect, number of collects + * and whether only followers can collect, charging a fee for collect and distributing it among Receiver/Referral/Treasury. + * @dev Here we use "Base" terminology to anything that represents this base functionality (base structs, base functions, base storage). + * @dev You can build your own collect modules on top of the "Base" by inheriting this contract and overriding functions. + * @dev This contract is marked "abstract" as it requires you to implement initializePublicationCollectModule and getPublicationData functions when you inherit from it. + * @dev See BaseFeeCollectModule as an example implementation. + */ +abstract contract BaseFeeCollectModule is + FeeModuleBase, + FollowValidationModuleBase, + IBaseFeeCollectModule +{ + using SafeERC20 for IERC20; + + mapping(uint256 => mapping(uint256 => BaseProfilePublicationData)) + internal _dataByPublicationByProfile; + + constructor(address hub, address moduleGlobals) ModuleBase(hub) FeeModuleBase(moduleGlobals) {} + + /** + * @dev Processes a collect by: + * 1. Validating that collect action meets all needded criteria + * 2. Processing the collect action either with or withour referral + * + * @inheritdoc ICollectModule + */ + function processCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external virtual onlyHub { + _validateAndStoreCollect(referrerProfileId, collector, profileId, pubId, data); + + if (referrerProfileId == profileId) { + _processCollect(collector, profileId, pubId, data); + } else { + _processCollectWithReferral(referrerProfileId, collector, profileId, pubId, data); + } + } + + // This function is not implemented because each Collect module has its own return data type + // function getPublicationData(uint256 profileId, uint256 pubId) external view returns (.....) {} + + /** + * @notice Returns the Base publication data for a given publication, or an empty struct if that publication was not + * initialized with this module. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * + * @return The BaseProfilePublicationData struct mapped to that publication. + */ + function getBasePublicationData(uint256 profileId, uint256 pubId) + public + view + virtual + returns (BaseProfilePublicationData memory) + { + return _dataByPublicationByProfile[profileId][pubId]; + } + + /** + * @notice Calculates and returns the collect fee of a publication. + * @dev Override this function to use a different formula for the fee. + * + * @param profileId The token ID of the profile mapped to the publication to query. + * @param pubId The publication ID of the publication to query. + * @param data Any additional params needed to calculate the fee. + * + * @return The collect fee of the specified publication. + */ + function calculateFee( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) public view virtual returns (uint160) { + return _dataByPublicationByProfile[profileId][pubId].amount; + } + + /** + * @dev Validates the Base parameters like: + * 1) Is the currency whitelisted + * 2) Is the referralFee in valid range + * 3) Is the end of collects timestamp in valid range + * + * This should be called during initializePublicationCollectModule() + * + * @param baseInitData Module initialization data (see BaseFeeCollectModuleInitData struct) + */ + function _validateBaseInitData(BaseFeeCollectModuleInitData memory baseInitData) + internal + virtual + { + if ( + !_currencyWhitelisted(baseInitData.currency) || + baseInitData.referralFee > BPS_MAX || + (baseInitData.endTimestamp != 0 && baseInitData.endTimestamp < block.timestamp) + ) revert Errors.InitParamsInvalid(); + } + + /** + * @dev Stores the initial module parameters + * + * This should be called during initializePublicationCollectModule() + * + * @param profileId The token ID of the profile publishing the publication. + * @param pubId The publication ID. + * @param baseInitData Module initialization data (see BaseFeeCollectModuleInitData struct) + */ + function _storeBasePublicationCollectParameters( + uint256 profileId, + uint256 pubId, + BaseFeeCollectModuleInitData memory baseInitData + ) internal virtual { + _dataByPublicationByProfile[profileId][pubId].amount = baseInitData.amount; + _dataByPublicationByProfile[profileId][pubId].collectLimit = baseInitData.collectLimit; + _dataByPublicationByProfile[profileId][pubId].currency = baseInitData.currency; + _dataByPublicationByProfile[profileId][pubId].recipient = baseInitData.recipient; + _dataByPublicationByProfile[profileId][pubId].referralFee = baseInitData.referralFee; + _dataByPublicationByProfile[profileId][pubId].followerOnly = baseInitData.followerOnly; + _dataByPublicationByProfile[profileId][pubId].endTimestamp = baseInitData.endTimestamp; + } + + /** + * @dev Validates the collect action by checking that: + * 1) the collector is a follower (if enabled) + * 2) the number of collects after the action doesn't surpass the collect limit (if enabled) + * 3) the current block timestamp doesn't surpass the end timestamp (if enabled) + * + * This should be called during processCollect() + * + * @param referrerProfileId The LensHub profile token ID of the referrer's profile (only different in case of mirrors). + * @param collector The collector address. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Arbitrary data __passed from the collector!__ to be decoded. + */ + function _validateAndStoreCollect( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal virtual { + uint96 collectsAfter = ++_dataByPublicationByProfile[profileId][pubId].currentCollects; + + if (_dataByPublicationByProfile[profileId][pubId].followerOnly) + _checkFollowValidity(profileId, collector); + + uint256 endTimestamp = _dataByPublicationByProfile[profileId][pubId].endTimestamp; + uint256 collectLimit = _dataByPublicationByProfile[profileId][pubId].collectLimit; + + if (collectLimit != 0 && collectsAfter > collectLimit) { + revert Errors.MintLimitExceeded(); + } + if (endTimestamp != 0 && block.timestamp > endTimestamp) { + revert Errors.CollectExpired(); + } + } + + /** + * @dev Internal processing of a collect: + * 1. Calculation of fees + * 2. Validation that fees are what collector expected + * 3. Transfer of fees to recipient(-s) and treasury + * + * @param collector The address that will collect the post. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Arbitrary data __passed from the collector!__ to be decoded. + */ + function _processCollect( + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal virtual { + uint256 amount = calculateFee(profileId, pubId, data); + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + (address treasury, uint16 treasuryFee) = _treasuryData(); + uint256 treasuryAmount = (amount * treasuryFee) / BPS_MAX; + + // Send amount after treasury cut, to all recipients + _transferToRecipients(currency, collector, profileId, pubId, amount - treasuryAmount); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @dev Internal processing of a collect with a referral(-s). + * + * Same as _processCollect, but also includes transfer to referral(-s): + * 1. Calculation of fees + * 2. Validation that fees are what collector expected + * 3. Transfer of fees to recipient(-s), referral(-s) and treasury + * + * @param referrerProfileId The address of the referral. + * @param collector The address that will collect the post. + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param data Arbitrary data __passed from the collector!__ to be decoded. + */ + function _processCollectWithReferral( + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + bytes calldata data + ) internal virtual { + uint256 amount = calculateFee(profileId, pubId, data); + address currency = _dataByPublicationByProfile[profileId][pubId].currency; + _validateDataIsExpected(data, currency, amount); + + address treasury; + uint256 treasuryAmount; + + // Avoids stack too deep + { + uint16 treasuryFee; + (treasury, treasuryFee) = _treasuryData(); + treasuryAmount = (amount * treasuryFee) / BPS_MAX; + } + + uint256 adjustedAmount = amount - treasuryAmount; + adjustedAmount = _transferToReferrals( + currency, + referrerProfileId, + collector, + profileId, + pubId, + adjustedAmount, + data + ); + + _transferToRecipients(currency, collector, profileId, pubId, adjustedAmount); + + if (treasuryAmount > 0) { + IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount); + } + } + + /** + * @dev Tranfers the fee to recipient(-s) + * + * Override this to add additional functionality (e.g. multiple recipients) + * + * @param currency Currency of the transaction + * @param collector The address that collects the post (and pays the fee). + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param amount Amount to transfer to recipient(-s) + */ + function _transferToRecipients( + address currency, + address collector, + uint256 profileId, + uint256 pubId, + uint256 amount + ) internal virtual { + address recipient = _dataByPublicationByProfile[profileId][pubId].recipient; + + if (amount > 0) { + IERC20(currency).safeTransferFrom(collector, recipient, amount); + } + } + + /** + * @dev Tranfers the part of fee to referral(-s) + * + * Override this to add additional functionality (e.g. multiple referrals) + * + * @param currency Currency of the transaction + * @param referrerProfileId The address of the referral. + * @param collector The address that collects the post (and pays the fee). + * @param profileId The token ID of the profile associated with the publication being collected. + * @param pubId The LensHub publication ID associated with the publication being collected. + * @param adjustedAmount Amount of the fee after subtracting the Treasury part. + * @param data Arbitrary data __passed from the collector!__ to be decoded. + */ + function _transferToReferrals( + address currency, + uint256 referrerProfileId, + address collector, + uint256 profileId, + uint256 pubId, + uint256 adjustedAmount, + bytes calldata data + ) internal virtual returns (uint256) { + uint256 referralFee = _dataByPublicationByProfile[profileId][pubId].referralFee; + if (referralFee != 0) { + // The reason we levy the referral fee on the adjusted amount is so that referral fees + // don't bypass the treasury fee, in essence referrals pay their fair share to the treasury. + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + if (referralAmount > 0) { + adjustedAmount = adjustedAmount - referralAmount; + + address referralRecipient = IERC721(HUB).ownerOf(referrerProfileId); + + // Send referral fee in normal ERC20 tokens + IERC20(currency).safeTransferFrom(collector, referralRecipient, referralAmount); + } + } + return adjustedAmount; + } +} diff --git a/lens-protocol/modules/contracts/collect/base/CarbonRetireBase.sol b/lens-protocol/modules/contracts/collect/base/CarbonRetireBase.sol new file mode 100644 index 0000000..9f744e0 --- /dev/null +++ b/lens-protocol/modules/contracts/collect/base/CarbonRetireBase.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +import '@openzeppelin/contracts/utils/Strings.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; + +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {IKlimaInfinity} from '../../interfaces/IKlimaInfinity.sol'; + +/** + * @title CarbonRetireBase + * @author + * + * @notice Abstract contract for carbon retirements + * + */ +abstract contract CarbonRetireBase { + using SafeERC20 for IERC20; + + // https://github.com/KlimaDAO/klimadao-solidity/blob/main/src/protocol/bonds/CarbonRetirementBondDepository.sol#L27 + address public immutable KLIMA_INFINITY; + + constructor(address _klimaInfinity) { + KLIMA_INFINITY = _klimaInfinity; + } + + /** + * @dev Performs carbon retirement + * + * @param collector The address that collects the post + * @param recipient The address that published the publication and receives the fee + * @param currency Fee currency of publication + * @param poolToken carbon pool token for retirement + * @param retirementAmount Amount of currency that goes into carbon retirement + */ + function _retireCarbon( + address collector, + address recipient, + address currency, + address poolToken, + uint256 retirementAmount, + string memory retiringEntityString, + string memory beneficiaryString, + string memory retirementMessage + ) internal { + // Transfer retirementAmount + // 2 transfers, because retirement function requires that token is received by msg.sender, + // which is collect module, not collector wallet (tx.origin). + IERC20(currency).safeTransferFrom(collector, address(this), retirementAmount); + IERC20(currency).safeTransfer(KLIMA_INFINITY, retirementAmount); + + // TODO: + // There's another safeTransferFrom inside retirement function, but with 0 amount + // https://github.com/KlimaDAO/klimadao-solidity/blob/88ff87907f8319407728b1488323ce9912cdd3ed/src/infinity/libraries/Token/LibTransfer.sol#L52 + // --> Will this require an approval by address(this)?? + // --> Does fromMode INTERNAL solve it? + + IKlimaInfinity(KLIMA_INFINITY).retireExactSourceDefault( + currency, + poolToken, + retirementAmount, + retiringEntityString, + recipient, + beneficiaryString, + retirementMessage, + 1 // TODO: Is 1 equal fromMode INTERNAL? https://github.com/KlimaDAO/klimadao-solidity/blob/88ff87907f8319407728b1488323ce9912cdd3ed/src/infinity/libraries/Token/LibTransfer.sol#L17 + ); + } + + /** + * @dev Check if retirementAggregator can swap from currency to poolToken. + * + * This function should not fail, but always return true/false + * Reason: processCollect should not fail, but instead lead to normal collect. + * + * @param sourceToken Address of the source token that is used to pay the retirement. + * @param poolToken Address of the carbon pool token that is used for retirement. + * @param amountIn Amount of the source token that is used for retirement. + * + * @return The ProfilePublicationData struct mapped to that publication. + */ + function checkRetirementSwapFeasibility( + address sourceToken, + address poolToken, + uint256 amountIn + ) public view returns (bool) { + if (!(amountIn > 0)) { + return false; + } + + // TODO: Check if desired behaviour is fulfilled: + // - _poolToken is not accepted by KlimaInfinity: return false + // - No swap path exists: return false + // - _poolToken accepted and swap path exists: return true + // - Check on liquidity/slippage/price_impact possible??? + + try + IKlimaInfinity(KLIMA_INFINITY).getRetireAmountSourceDefault( + sourceToken, + poolToken, + amountIn + ) + returns (uint256 amountOut) { + if (!(amountOut > 0)) { + return false; + } + } catch { + return false; + } + return true; + } +} diff --git a/lens-protocol/modules/contracts/collect/base/IBaseFeeCollectModule.sol b/lens-protocol/modules/contracts/collect/base/IBaseFeeCollectModule.sol new file mode 100644 index 0000000..91443df --- /dev/null +++ b/lens-protocol/modules/contracts/collect/base/IBaseFeeCollectModule.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +import {ICollectModule} from '@aave/lens-protocol/contracts/interfaces/ICollectModule.sol'; + +/** + * @notice A struct containing the necessary data to execute collect actions on a publication. + * + * @param amount The collecting cost associated with this publication. 0 for free collect. + * @param collectLimit The maximum number of collects for this publication. 0 for no limit. + * @param currency The currency associated with this publication. + * @param currentCollects The current number of collects for this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly True if only followers of publisher may collect the post. + * @param endTimestamp The end timestamp after which collecting is impossible. 0 for no expiry. + * @param recipient Recipient of collect fees. + */ +struct BaseProfilePublicationData { + uint160 amount; + uint96 collectLimit; + address currency; + uint96 currentCollects; + address recipient; + uint16 referralFee; + bool followerOnly; + uint72 endTimestamp; +} + +/** + * @notice A struct containing the necessary data to initialize this Base Collect Module. + * + * @param amount The collecting cost associated with this publication. 0 for free collect. + * @param collectLimit The maximum number of collects for this publication. 0 for no limit. + * @param currency The currency associated with this publication. + * @param referralFee The referral fee associated with this publication. + * @param followerOnly True if only followers of publisher may collect the post. + * @param endTimestamp The end timestamp after which collecting is impossible. 0 for no expiry. + * @param recipient Recipient of collect fees. + */ +struct BaseFeeCollectModuleInitData { + uint160 amount; + uint96 collectLimit; + address currency; + uint16 referralFee; + bool followerOnly; + uint72 endTimestamp; + address recipient; +} + +interface IBaseFeeCollectModule is ICollectModule { + function getBasePublicationData(uint256 profileId, uint256 pubId) + external + view + returns (BaseProfilePublicationData memory); + + function calculateFee( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external view returns (uint160); +} diff --git a/lens-protocol/modules/contracts/interfaces/IERC20Burnable.sol b/lens-protocol/modules/contracts/interfaces/IERC20Burnable.sol new file mode 100644 index 0000000..ac410ca --- /dev/null +++ b/lens-protocol/modules/contracts/interfaces/IERC20Burnable.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) + +pragma solidity 0.8.10; + +/** + * @dev Extension of the ERC20 standard to support burning. + */ +interface IERC20Burnable { + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `from` to `to` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address from, + address to, + uint256 amount + ) external returns (bool); + + /** + * @dev Destroys `amount` tokens from the caller. + * + * See {ERC20-_burn}. + */ + function burn(uint256 amount) external; + + /** + * @dev Destroys `amount` tokens from `account`, deducting from the caller's + * allowance. + * + * See {ERC20-_burn} and {ERC20-allowance}. + * + * Requirements: + * + * - the caller must have allowance for ``accounts``'s tokens of at least + * `amount`. + */ + function burnFrom(address account, uint256 amount) external; + + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} diff --git a/lens-protocol/modules/contracts/interfaces/IKlimaInfinity.sol b/lens-protocol/modules/contracts/interfaces/IKlimaInfinity.sol new file mode 100644 index 0000000..8c24294 --- /dev/null +++ b/lens-protocol/modules/contracts/interfaces/IKlimaInfinity.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +interface IKlimaInfinity { + // https://github.com/KlimaDAO/klimadao-solidity/blob/main/src/infinity/facets/Retire/RetireSourceFacet.sol#L35 + function retireExactSourceDefault( + address sourceToken, + address poolToken, + uint256 maxAmountIn, + string memory retiringEntityString, + address beneficiaryAddress, + string memory beneficiaryString, + string memory retirementMessage, + uint8 fromMode + ) external payable returns (uint256 retirementIndex); + + /* Views */ + + // https://github.com/KlimaDAO/klimadao-solidity/blob/main/src/infinity/facets/RetirementQuoter.sol#L88 + function getRetireAmountSourceDefault( + address sourceToken, + address carbonToken, + uint amount + ) external view returns (uint amountOut); +} diff --git a/lens-protocol/modules/contracts/interfaces/IPoolDataProvider.sol b/lens-protocol/modules/contracts/interfaces/IPoolDataProvider.sol new file mode 100644 index 0000000..86fd9a3 --- /dev/null +++ b/lens-protocol/modules/contracts/interfaces/IPoolDataProvider.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: AGPL-3.0 +pragma solidity ^0.8.0; + +interface IPoolDataProvider { + /** + * @notice Returns the configuration data of the reserve. + * @dev Not returning borrow and supply caps for compatibility, nor pause flag. + * @param asset The address of the underlying asset of the reserve. + * @return decimals The number of decimals of the reserve. + * @return ltv The ltv of the reserve. + * @return liquidationThreshold The liquidationThreshold of the reserve. + * @return liquidationBonus The liquidationBonus of the reserve. + * @return reserveFactor The reserveFactor of the reserve. + * @return usageAsCollateralEnabled True if the usage as collateral is enabled, false otherwise. + * @return borrowingEnabled True if borrowing is enabled, false otherwise. + * @return stableBorrowRateEnabled True if stable rate borrowing is enabled, false otherwise. + * @return isActive True if it is active, false otherwise. + * @return isFrozen True if it is frozen, false otherwise. + **/ + function getReserveConfigurationData(address asset) + external + view + returns ( + uint256 decimals, + uint256 ltv, + uint256 liquidationThreshold, + uint256 liquidationBonus, + uint256 reserveFactor, + bool usageAsCollateralEnabled, + bool borrowingEnabled, + bool stableBorrowRateEnabled, + bool isActive, + bool isFrozen + ); +} diff --git a/lens-protocol/modules/contracts/mocks/ACurrency.sol b/lens-protocol/modules/contracts/mocks/ACurrency.sol new file mode 100644 index 0000000..ed0f350 --- /dev/null +++ b/lens-protocol/modules/contracts/mocks/ACurrency.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity 0.8.10; + +import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; + +contract ACurrency is ERC20('ACurrency', 'aCRNC') { + function mint(address to, uint256 amount) external { + _mint(to, amount); + } + + function burnFrom(address from, uint256 amount) external { + _burn(from, amount); + } +} \ No newline at end of file diff --git a/lens-protocol/modules/contracts/mocks/MockKlimaRetirementAggregator.sol b/lens-protocol/modules/contracts/mocks/MockKlimaRetirementAggregator.sol new file mode 100644 index 0000000..8ad82c5 --- /dev/null +++ b/lens-protocol/modules/contracts/mocks/MockKlimaRetirementAggregator.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity 0.8.10; + +import {IERC20Burnable} from '../interfaces/IERC20Burnable.sol'; + +contract MockKlimaRetirementAggregator { + + function retireCarbonFrom ( + address _recipient, + address _sourceToken, + address _poolToken, + uint256 _amount, + bool _amountInCarbon, + address _beneficiaryAddress, + string memory _beneficiaryString, + string memory _retirementMessage + ) external { + // The actual contract would swap for and properly retire BCT + IERC20Burnable(_sourceToken).burnFrom(address(this), _amount); + } +} \ No newline at end of file diff --git a/lens-protocol/modules/contracts/mocks/MockPool.sol b/lens-protocol/modules/contracts/mocks/MockPool.sol new file mode 100644 index 0000000..3351e35 --- /dev/null +++ b/lens-protocol/modules/contracts/mocks/MockPool.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity 0.8.10; + +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +interface IAToken { + function mint(address to, uint256 amount) external; +} + +contract MockPool { + address public aTokenAddress; + address public unsupportedToken; + + error UnsupportedTokenSupplied(); + + constructor(address _aTokenAddress, address _unsupportedToken) { + aTokenAddress = _aTokenAddress; + unsupportedToken = _unsupportedToken; + } + + function supply( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode + ) external { + if (asset == unsupportedToken) revert UnsupportedTokenSupplied(); + + IERC20(asset).transferFrom(msg.sender, aTokenAddress, amount); + + IAToken(aTokenAddress).mint(onBehalfOf, amount); + } +} diff --git a/lens-protocol/modules/contracts/mocks/MockPoolAddressesProvider.sol b/lens-protocol/modules/contracts/mocks/MockPoolAddressesProvider.sol new file mode 100644 index 0000000..1861b66 --- /dev/null +++ b/lens-protocol/modules/contracts/mocks/MockPoolAddressesProvider.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity 0.8.10; + +contract MockPoolAddressesProvider { + address public pool; + + constructor(address _pool) { + pool = _pool; + } + + function getPool() public view returns (address) { + return pool; + } +} diff --git a/lens-protocol/modules/contracts/mocks/MockVault.sol b/lens-protocol/modules/contracts/mocks/MockVault.sol new file mode 100644 index 0000000..81aaa13 --- /dev/null +++ b/lens-protocol/modules/contracts/mocks/MockVault.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity 0.8.10; + +import {ERC4626} from 'solmate/src/mixins/ERC4626.sol'; +import {ERC20} from 'solmate/src/tokens/ERC20.sol'; + +contract MockVault is ERC4626 { + constructor(ERC20 _asset) ERC4626(_asset, 'MockVault Shares', 'MVS') {} + + function totalAssets() public view override returns (uint256) { + return asset.balanceOf(address(this)); + } +} diff --git a/lens-protocol/modules/contracts/mocks/NFT.sol b/lens-protocol/modules/contracts/mocks/NFT.sol new file mode 100644 index 0000000..1dbbf20 --- /dev/null +++ b/lens-protocol/modules/contracts/mocks/NFT.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {ERC721} from '@openzeppelin/contracts/token/ERC721/ERC721.sol'; + +contract NFT is ERC721('NFT', 'NFT') { + function mint(address to, uint256 nftId) external { + _mint(to, nftId); + } +} diff --git a/lens-protocol/modules/contracts/reference/DegreesOfSeparationReferenceModule.sol b/lens-protocol/modules/contracts/reference/DegreesOfSeparationReferenceModule.sol new file mode 100644 index 0000000..e9e5f1f --- /dev/null +++ b/lens-protocol/modules/contracts/reference/DegreesOfSeparationReferenceModule.sol @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {DataTypes} from '@aave/lens-protocol/contracts/libraries/DataTypes.sol'; +import {EIP712} from '@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol'; +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {Events} from '@aave/lens-protocol/contracts/libraries/Events.sol'; +import {FollowValidationModuleBase} from '@aave/lens-protocol/contracts/core/modules/FollowValidationModuleBase.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; +import {IFollowModule} from '@aave/lens-protocol/contracts/interfaces/IFollowModule.sol'; +import {ILensHub} from '@aave/lens-protocol/contracts/interfaces/ILensHub.sol'; +import {IReferenceModule} from '@aave/lens-protocol/contracts/interfaces/IReferenceModule.sol'; +import {ModuleBase} from '@aave/lens-protocol/contracts/core/modules/ModuleBase.sol'; + +/** + * @notice Struct representing the module configuration for certain publication. + * + * @param setUp Indicates if the publication was set up to use this module, to then allow updating params. + * @param commentsRestricted Indicates if the comment operation is restricted or open to everyone. + * @param mirrorsRestricted Indicates if the mirror operation is restricted or open to everyone. + * @param degreesOfSeparation The max degrees of separation allowed for restricted operations. + */ +struct ModuleConfig { + bool setUp; + bool commentsRestricted; + bool mirrorsRestricted; + uint8 degreesOfSeparation; +} + +/** + * @title DegreesOfSeparationReferenceModule + * @author Lens Protocol + * + * @notice This reference module allows to set a degree of separation `n`, and then allows to comment/mirror only to + * profiles that are at most at `n` degrees of separation from the author of the root publication. + */ +contract DegreesOfSeparationReferenceModule is + EIP712, + FollowValidationModuleBase, + IReferenceModule +{ + event ModuleParametersUpdated( + uint256 indexed profileId, + uint256 indexed pubId, + bool commentsRestricted, + bool mirrorsRestricted, + uint8 degreesOfSeparation + ); + + error InvalidDegreesOfSeparation(); + error OperationDisabled(); + error ProfilePathExceedsDegreesOfSeparation(); + error PublicationNotSetUp(); + + /** + * @dev Because of the "Six degrees of separation" theory, in the long term, setting up 5, 6 or more degrees of + * separation will be almost equivalent to turning off the restriction. + * If we also take into account the gas cost of performing the validations on-chain, makes sense to only support up + * to 4 degrees of separation. + */ + uint8 constant MAX_DEGREES_OF_SEPARATION = 4; + + mapping(address => uint256) public nonces; + + mapping(uint256 => mapping(uint256 => ModuleConfig)) internal _moduleConfigByPubByProfile; + + constructor(address hub) EIP712('DegreesOfSeparationReferenceModule', '1') ModuleBase(hub) {} + + /** + * @notice Initializes data for a given publication being published. This can only be called by the hub. + * + * @param profileId The token ID of the profile publishing the publication. + * @param pubId The associated publication's LensHub publication ID. + * @param data Arbitrary data passed from the user to be decoded. + * + * @return bytes An abi encoded byte array encapsulating the execution's state changes. This will be emitted by the + * hub alongside the collect module's address and should be consumed by front ends. + */ + function initializeReferenceModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + (bool commentsRestricted, bool mirrorsRestricted, uint8 degreesOfSeparation) = abi.decode( + data, + (bool, bool, uint8) + ); + if (degreesOfSeparation > MAX_DEGREES_OF_SEPARATION) { + revert InvalidDegreesOfSeparation(); + } + _moduleConfigByPubByProfile[profileId][pubId] = ModuleConfig( + true, + commentsRestricted, + mirrorsRestricted, + degreesOfSeparation + ); + return data; + } + + /** + * @notice Processes a comment action referencing a given publication. This can only be called by the hub. + * + * @dev It will apply the degrees of separation restriction if the publication has `commentsRestricted` enabled. + * + * @param profileId The token ID of the profile associated with the publication being published. + * @param profileIdPointed The profile ID of the profile associated the publication being referenced. + * @param pubIdPointed The publication ID of the publication being referenced. + * @param data Encoded data containing the array of profile IDs representing the follower path between the owner of + * the author of the root publication and the profile authoring the comment. + */ + function processComment( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external view override onlyHub { + if (_moduleConfigByPubByProfile[profileIdPointed][pubIdPointed].commentsRestricted) { + _validateDegreesOfSeparationRestriction( + profileId, + profileIdPointed, + _moduleConfigByPubByProfile[profileIdPointed][pubIdPointed].degreesOfSeparation, + abi.decode(data, (uint256[])) + ); + } + } + + /** + * @notice Processes a mirror action referencing a given publication. This can only be called by the hub. + * + * @dev It will apply the degrees of separation restriction if the publication has `mirrorsRestricted` enabled. + * + * @param profileId The token ID of the profile associated with the publication being published. + * @param profileIdPointed The profile ID of the profile associated the publication being referenced. + * @param pubIdPointed The publication ID of the publication being referenced. + * @param data Encoded data containing the array of profile IDs representing the follower path between the owner of + * the author of the root publication and the profile authoring the mirror. + */ + function processMirror( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external view override onlyHub { + if (_moduleConfigByPubByProfile[profileIdPointed][pubIdPointed].mirrorsRestricted) { + _validateDegreesOfSeparationRestriction( + profileId, + profileIdPointed, + _moduleConfigByPubByProfile[profileIdPointed][pubIdPointed].degreesOfSeparation, + abi.decode(data, (uint256[])) + ); + } + } + + /** + * @notice Updates the module parameters for the given publication. + * + * @param profileId The token ID of the profile publishing the publication. + * @param pubId The associated publication's LensHub publication ID. + * @param commentsRestricted Indicates if the comment operation is restricted or open to everyone. + * @param mirrorsRestricted Indicates if the mirror operation is restricted or open to everyone. + * @param degreesOfSeparation The max degrees of separation allowed for restricted operations. + */ + function updateModuleParameters( + uint256 profileId, + uint256 pubId, + bool commentsRestricted, + bool mirrorsRestricted, + uint8 degreesOfSeparation + ) external { + _updateModuleParameters( + profileId, + pubId, + commentsRestricted, + mirrorsRestricted, + degreesOfSeparation, + msg.sender + ); + } + + /** + * @notice Updates the module parameters for the given publication through EIP-712 signatures. + * + * @param profileId The token ID of the profile publishing the publication. + * @param pubId The associated publication's LensHub publication ID. + * @param commentsRestricted Indicates if the comment operation is restricted or open to everyone. + * @param mirrorsRestricted Indicates if the mirror operation is restricted or open to everyone. + * @param degreesOfSeparation The max degrees of separation allowed for restricted operations. + * @param operator The address that is executing this parameter update. Should match the recovered signer. + * @param sig The EIP-712 signature for this operation. + */ + function updateModuleParametersWithSig( + uint256 profileId, + uint256 pubId, + bool commentsRestricted, + bool mirrorsRestricted, + uint8 degreesOfSeparation, + address operator, + DataTypes.EIP712Signature calldata sig + ) external { + _validateUpdateModuleParametersSignature( + profileId, + pubId, + commentsRestricted, + mirrorsRestricted, + degreesOfSeparation, + operator, + sig + ); + _updateModuleParameters( + profileId, + pubId, + commentsRestricted, + mirrorsRestricted, + degreesOfSeparation, + operator + ); + } + + /** + * @notice Gets the module configuration for the given publication. + * + * @param profileId The token ID of the profile publishing the publication. + * @param pubId The associated publication's LensHub publication ID. + * + * @return ModuleConfig The module configuration set for the given publication. + */ + function getModuleConfig(uint256 profileId, uint256 pubId) + external + view + returns (ModuleConfig memory) + { + return _moduleConfigByPubByProfile[profileId][pubId]; + } + + /** + * @dev The data has encoded an array of integers, each integer is a profile ID, the whole array represents a path + * of `n` profiles. + * + * Let's define `X --> Y` as `The owner of X is following Y`. Then, being `path[i]` the i-th profile in the path, + * the following condition must be met for a given path of `n` profiles: + * + * profileIdPointed --> path[0] --> path[1] --> path[2] --> ... --> path[n-2] --> path[n-1] --> profileId + * + * @param profileId The token ID of the profile associated with the publication being published. + * @param profileIdPointed The profile ID of the profile associated the publication being referenced. + * @param degreesOfSeparation The degrees of separations configured for the given publication. + * @param profilePath The array of profile IDs representing the follower path between the owner of the author of the + * root publication and the profile authoring the comment. + */ + function _validateDegreesOfSeparationRestriction( + uint256 profileId, + uint256 profileIdPointed, + uint8 degreesOfSeparation, + uint256[] memory profilePath + ) internal view { + if (degreesOfSeparation == 0) { + revert OperationDisabled(); + } + if (profilePath.length > degreesOfSeparation - 1) { + revert ProfilePathExceedsDegreesOfSeparation(); + } + address follower = IERC721(HUB).ownerOf(profileIdPointed); + if (profilePath.length > 0) { + // Checks the owner of the profile authoring the root publication follows the first profile in the path. + // In the previous notation: profileIdPointed --> path[0] + _checkFollowValidity(profilePath[0], follower); + // Checks each profile owner in the path is following the profile coming next, according the order. + // In the previous notaiton: path[0] --> path[1] --> path[2] --> ... --> path[n-2] --> path[n-1] + uint256 i; + while (i < profilePath.length - 1) { + follower = IERC721(HUB).ownerOf(profilePath[i]); + unchecked { + ++i; + } + _checkFollowValidity(profilePath[i], follower); + } + // Checks the last profile in the path follows the profile commenting/mirroring. + // In the previous notation: path[n-1] --> profileId + follower = IERC721(HUB).ownerOf(profilePath[i]); + _checkFollowValidity(profileId, follower); + } else { + // Checks the owner of the profile authoring the root publication follows the profile commenting/mirroring. + // In the previous notation: profileIdPointed --> profileId + _checkFollowValidity(profileId, follower); + } + } + + /** + * @notice Internal function to abstract the logic regarding the parameter updating. + * + * @param profileId The token ID of the profile publishing the publication. + * @param pubId The associated publication's LensHub publication ID. + * @param commentsRestricted Indicates if the comment operation is restricted or open to everyone. + * @param mirrorsRestricted Indicates if the mirror operation is restricted or open to everyone. + * @param degreesOfSeparation The max degrees of separation allowed for restricted operations. + * @param operator The address that is executing this parameter update. Should match the recovered signer. + */ + function _updateModuleParameters( + uint256 profileId, + uint256 pubId, + bool commentsRestricted, + bool mirrorsRestricted, + uint8 degreesOfSeparation, + address operator + ) internal { + if (IERC721(HUB).ownerOf(profileId) != operator) { + revert Errors.NotProfileOwner(); + } + if (!_moduleConfigByPubByProfile[profileId][pubId].setUp) { + revert PublicationNotSetUp(); + } + if (degreesOfSeparation > MAX_DEGREES_OF_SEPARATION) { + revert InvalidDegreesOfSeparation(); + } + _moduleConfigByPubByProfile[profileId][pubId] = ModuleConfig( + true, + commentsRestricted, + mirrorsRestricted, + degreesOfSeparation + ); + emit ModuleParametersUpdated( + profileId, + pubId, + commentsRestricted, + mirrorsRestricted, + degreesOfSeparation + ); + } + + /** + * @notice Checks if the signature for the `UpdateModuleParametersWithSig` function is valid according EIP-712. + * + * @param profileId The token ID of the profile associated with the publication. + * @param pubId The publication ID associated with the publication. + * @param commentsRestricted Indicates if the comment operation is restricted or open to everyone. + * @param mirrorsRestricted Indicates if the mirror operation is restricted or open to everyone. + * @param degreesOfSeparation The max degrees of separation allowed for restricted operations. + * @param operator The address that is executing this parameter update. Should match the recovered signer. + * @param sig The EIP-712 signature for this operation. + */ + function _validateUpdateModuleParametersSignature( + uint256 profileId, + uint256 pubId, + bool commentsRestricted, + bool mirrorsRestricted, + uint8 degreesOfSeparation, + address operator, + DataTypes.EIP712Signature calldata sig + ) internal { + unchecked { + _validateRecoveredAddress( + _calculateDigest( + abi.encode( + keccak256( + 'UpdateModuleParametersWithSig(uint256 profileId,uint256 pubId,bool commentsRestricted,bool mirrorsRestricted,uint8 degreesOfSeparation,uint256 nonce,uint256 deadline)' + ), + profileId, + pubId, + commentsRestricted, + mirrorsRestricted, + degreesOfSeparation, + nonces[operator]++, + sig.deadline + ) + ), + operator, + sig + ); + } + } + + /** + * @notice Checks the recovered address is the expected signer for the given signature. + * + * @param digest The expected signed data. + * @param expectedAddress The address of the expected signer. + * @param sig The signature. + */ + function _validateRecoveredAddress( + bytes32 digest, + address expectedAddress, + DataTypes.EIP712Signature calldata sig + ) internal view { + if (sig.deadline < block.timestamp) { + revert Errors.SignatureExpired(); + } + address recoveredAddress = ecrecover(digest, sig.v, sig.r, sig.s); + if (recoveredAddress == address(0) || recoveredAddress != expectedAddress) { + revert Errors.SignatureInvalid(); + } + } + + /** + * @notice Calculates the digest for the given bytes according EIP-712 standard. + * + * @param message The message, as bytes, to calculate the digest from. + */ + function _calculateDigest(bytes memory message) internal view returns (bytes32) { + return keccak256(abi.encodePacked('\x19\x01', _domainSeparatorV4(), keccak256(message))); + } +} diff --git a/lens-protocol/modules/contracts/reference/TokenGatedReferenceModule.sol b/lens-protocol/modules/contracts/reference/TokenGatedReferenceModule.sol new file mode 100644 index 0000000..ef2e929 --- /dev/null +++ b/lens-protocol/modules/contracts/reference/TokenGatedReferenceModule.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.10; + +import {IReferenceModule} from '@aave/lens-protocol/contracts/interfaces/IReferenceModule.sol'; +import {ModuleBase} from '@aave/lens-protocol/contracts/core/modules/ModuleBase.sol'; +import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; + +interface IToken { + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); +} + +/** + * @notice A struct containing the necessary data to execute TokenGated references. + * + * @param tokenAddress The address of ERC20/ERC721 token used for gating the reference + * @param minThreshold The minimum balance threshold of the gated token required to execute a reference + */ +struct GateParams { + address tokenAddress; + uint256 minThreshold; +} + +/** + * @title TokenGatedReferenceModule + * @author Lens Protocol + * + * @notice A reference module that validates that the user who tries to reference has a required minimum balance of ERC20/ERC721 token. + */ +contract TokenGatedReferenceModule is ModuleBase, IReferenceModule { + uint256 internal constant UINT256_BYTES = 32; + + event TokenGatedReferencePublicationCreated( + uint256 indexed profileId, + uint256 indexed pubId, + address tokenAddress, + uint256 minThreshold + ); + + error NotEnoughBalance(); + + mapping(uint256 => mapping(uint256 => GateParams)) internal _gateParamsByPublicationByProfile; + + constructor(address hub) ModuleBase(hub) {} + + /** + * @dev The gating token address and minimum balance threshold is passed during initialization in data field (see `GateParams` struct) + * + * @inheritdoc IReferenceModule + */ + function initializeReferenceModule( + uint256 profileId, + uint256 pubId, + bytes calldata data + ) external override onlyHub returns (bytes memory) { + GateParams memory gateParams = abi.decode(data, (GateParams)); + + // Checking if the tokenAddress resembles ERC20/ERC721 token (by calling balanceOf() function) + (bool success, bytes memory result) = gateParams.tokenAddress.staticcall( + abi.encodeWithSignature('balanceOf(address)', address(this)) + ); + // We don't check if the contract exists cause we expect the return data anyway + if (gateParams.minThreshold == 0 || !success || result.length != UINT256_BYTES) + revert Errors.InitParamsInvalid(); + + _gateParamsByPublicationByProfile[profileId][pubId] = gateParams; + emit TokenGatedReferencePublicationCreated( + profileId, + pubId, + gateParams.tokenAddress, + gateParams.minThreshold + ); + return data; + } + + /** + * @notice Validates that the commenting profile's owner has enough balance of the gating token. + */ + function processComment( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external view override onlyHub { + _validateTokenBalance(profileId, profileIdPointed, pubIdPointed); + } + + /** + * @notice Validates that the mirroring profile's owner has enough balance of the gating token. + */ + function processMirror( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed, + bytes calldata data + ) external view override onlyHub { + _validateTokenBalance(profileId, profileIdPointed, pubIdPointed); + } + + /** + * @dev Validates the profile's owner balance of gating token. + * @dev Can work with both ERC20 and ERC721 as both interfaces support balanceOf() call + */ + function _validateTokenBalance( + uint256 profileId, + uint256 profileIdPointed, + uint256 pubIdPointed + ) internal view { + GateParams memory gateParams = _gateParamsByPublicationByProfile[profileIdPointed][ + pubIdPointed + ]; + if ( + IToken(gateParams.tokenAddress).balanceOf(IERC721(HUB).ownerOf(profileId)) < + gateParams.minThreshold + ) { + revert NotEnoughBalance(); + } + } +} diff --git a/lens-protocol/modules/foundry.toml b/lens-protocol/modules/foundry.toml new file mode 100644 index 0000000..9e0dd0c --- /dev/null +++ b/lens-protocol/modules/foundry.toml @@ -0,0 +1,23 @@ +[profile.default] +src = 'contracts' +out = 'out' +libs = ['node_modules', 'lib'] +test = 'test/foundry' +cache_path = 'forge-cache' +solc_version = '0.8.10' +optimizer = true +optimizer_runs = 99999 +fs_permissions = [{ access = "read", path = "./addresses.json"}] + +[rpc_endpoints] +polygon = "${POLYGON_RPC_URL}" +mumbai = "${MUMBAI_RPC_URL}" + +[etherscan] +polygon = { key = "${BLOCK_EXPLORER_KEY}" } +mumbai = { key = "${BLOCK_EXPLORER_KEY}" } + +[fuzz] +runs = 10000 + +# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/lens-protocol/modules/hardhat.config.ts b/lens-protocol/modules/hardhat.config.ts new file mode 100644 index 0000000..dc84fbd --- /dev/null +++ b/lens-protocol/modules/hardhat.config.ts @@ -0,0 +1,115 @@ +import { HardhatUserConfig } from 'hardhat/types'; +import { accounts } from './helpers/test-wallets'; +import { HARDHATEVM_CHAINID } from './helpers/hardhat-constants'; +import { NETWORKS_RPC_URL } from './helper-hardhat-config'; +import dotenv from 'dotenv'; +import glob from 'glob'; +import path from 'path'; +dotenv.config({ path: '../.env' }); + +import 'hardhat-dependency-compiler'; +import '@nomiclabs/hardhat-ethers'; +import '@nomiclabs/hardhat-etherscan'; +import '@typechain/hardhat'; +import 'solidity-coverage'; +import 'hardhat-gas-reporter'; +import 'hardhat-contract-sizer'; +import 'hardhat-log-remover'; +import 'hardhat-spdx-license-identifier'; +import { eEthereumNetwork, eNetwork, ePolygonNetwork, eXDaiNetwork } from './helpers/types'; + +if (!process.env.SKIP_LOAD) { + glob.sync('./tasks/**/*.ts').forEach(function (file) { + require(path.resolve(file)); + }); +} + +const DEFAULT_BLOCK_GAS_LIMIT = 12450000; +const MNEMONIC_PATH = "m/44'/60'/0'/0"; +const MNEMONIC = process.env.MNEMONIC || ''; +const MAINNET_FORK = process.env.MAINNET_FORK === 'true'; +const TRACK_GAS = process.env.TRACK_GAS === 'true'; +const BLOCK_EXPLORER_KEY = process.env.BLOCK_EXPLORER_KEY || ''; + +const getCommonNetworkConfig = (networkName: eNetwork, networkId: number) => ({ + url: NETWORKS_RPC_URL[networkName] ?? '', + accounts: { + mnemonic: MNEMONIC, + path: MNEMONIC_PATH, + initialIndex: 0, + count: 20, + }, +}); + +const mainnetFork = MAINNET_FORK + ? { + blockNumber: 12012081, + url: NETWORKS_RPC_URL['main'], + } + : undefined; + +const config: HardhatUserConfig = { + solidity: { + compilers: [ + { + version: '0.8.10', + settings: { + optimizer: { + enabled: true, + runs: 200, + details: { + yul: true, + }, + }, + }, + }, + ], + }, + networks: { + kovan: getCommonNetworkConfig(eEthereumNetwork.kovan, 42), + ropsten: getCommonNetworkConfig(eEthereumNetwork.ropsten, 3), + main: getCommonNetworkConfig(eEthereumNetwork.main, 1), + tenderlyMain: getCommonNetworkConfig(eEthereumNetwork.tenderlyMain, 3030), + matic: getCommonNetworkConfig(ePolygonNetwork.matic, 137), + mumbai: getCommonNetworkConfig(ePolygonNetwork.mumbai, 80001), + xdai: getCommonNetworkConfig(eXDaiNetwork.xdai, 100), + hardhat: { + hardfork: 'london', + blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT, + gas: DEFAULT_BLOCK_GAS_LIMIT, + gasPrice: 8000000000, + chainId: HARDHATEVM_CHAINID, + throwOnTransactionFailures: true, + throwOnCallFailures: true, + accounts: accounts.map(({ secretKey, balance }: { secretKey: string; balance: string }) => ({ + privateKey: secretKey, + balance, + })), + forking: mainnetFork, + }, + }, + gasReporter: { + enabled: TRACK_GAS, + }, + spdxLicenseIdentifier: { + overwrite: false, + runOnCompile: false, + }, + etherscan: { + apiKey: BLOCK_EXPLORER_KEY, + }, + dependencyCompiler: { + paths: [ + '@aave/lens-protocol/contracts/core/LensHub.sol', + '@aave/lens-protocol/contracts/core/modules/ModuleGlobals.sol', + '@aave/lens-protocol/contracts/core/modules/collect/FreeCollectModule.sol', + '@aave/lens-protocol/contracts/core/modules/follow/ProfileFollowModule.sol', + '@aave/lens-protocol/contracts/core/FollowNFT.sol', + '@aave/lens-protocol/contracts/core/CollectNFT.sol', + '@aave/lens-protocol/contracts/mocks/Currency.sol', + '@aave/lens-protocol/contracts/upgradeability/TransparentUpgradeableProxy.sol', + ], + }, +}; + +export default config; diff --git a/lens-protocol/modules/helper-hardhat-config.ts b/lens-protocol/modules/helper-hardhat-config.ts new file mode 100644 index 0000000..fcc3eb6 --- /dev/null +++ b/lens-protocol/modules/helper-hardhat-config.ts @@ -0,0 +1,25 @@ +import { + eEthereumNetwork, + ePolygonNetwork, + eXDaiNetwork, + iParamsPerNetwork, +} from './helpers/types'; + +import dotenv from 'dotenv'; +dotenv.config({}); + +const TENDERLY_FORK_ID = process.env.TENDERLY_FORK_ID || ''; + +const GWEI = 1000 * 1000 * 1000; + +export const NETWORKS_RPC_URL: iParamsPerNetwork = { + [eEthereumNetwork.kovan]: process.env.KOVAN_RPC_URL, + [eEthereumNetwork.ropsten]: process.env.ROPSTEN_RPC_URL, + [eEthereumNetwork.main]: process.env.MAINNET_RPC_URL, + [eEthereumNetwork.hardhat]: 'http://localhost:8545', + [eEthereumNetwork.harhatevm]: 'http://localhost:8545', + [eEthereumNetwork.tenderlyMain]: `https://rpc.tenderly.co/fork/${TENDERLY_FORK_ID}`, + [ePolygonNetwork.mumbai]: process.env.MUMBAI_RPC_URL, + [ePolygonNetwork.matic]: process.env.POLYGON_RPC_URL, + [eXDaiNetwork.xdai]: 'https://rpc.xdaichain.com/', +}; diff --git a/lens-protocol/modules/helpers/hardhat-constants.ts b/lens-protocol/modules/helpers/hardhat-constants.ts new file mode 100644 index 0000000..9237b39 --- /dev/null +++ b/lens-protocol/modules/helpers/hardhat-constants.ts @@ -0,0 +1,2 @@ +export const TEST_SNAPSHOT_ID = '0x1'; +export const HARDHATEVM_CHAINID = 31337; diff --git a/lens-protocol/modules/helpers/test-wallets.ts b/lens-protocol/modules/helpers/test-wallets.ts new file mode 100644 index 0000000..8935d96 --- /dev/null +++ b/lens-protocol/modules/helpers/test-wallets.ts @@ -0,0 +1,44 @@ +const balance = '1000000000000000000000000'; + +export const accounts = [ + { + secretKey: '0xc5e8f61d1ab959b397eecc0a37a6517b8e67a0e7cf1f4bce5591f3ed80199122', + balance, + }, + { + secretKey: '0xd49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb', + balance, + }, + { + secretKey: '0x23c601ae397441f3ef6f1075dcb0031ff17fb079837beadaf3c84d96c6f3e569', + balance, + }, + { + secretKey: '0xee9d129c1997549ee09c0757af5939b2483d80ad649a0eda68e8b0357ad11131', + balance, + }, + { + secretKey: '0x87630b2d1de0fbd5044eb6891b3d9d98c34c8d310c852f98550ba774480e47cc', + balance, + }, + { + secretKey: '0x275cc4a2bfd4f612625204a20a2280ab53a6da2d14860c47a9f5affe58ad86d4', + balance, + }, + { + secretKey: '0xaee25d55ce586148a853ca83fdfacaf7bc42d5762c6e7187e6f8e822d8e6a650', + balance, + }, + { + secretKey: '0xa2e0097c961c67ec197b6865d7ecea6caffc68ebeb00e6050368c8f67fc9c588', + balance, + }, + { + secretKey: '0xb2e0097c961c67ec197b6865d7ecea6caffc68ebeb00e6050368c8f67fc9c569', + balance, + }, + { + secretKey: '0xc2e0097c961c67ec197b6865d7ecea6caffc68ebeb00e6050368c8f67fc9c500', + balance, + }, +]; diff --git a/lens-protocol/modules/helpers/types.ts b/lens-protocol/modules/helpers/types.ts new file mode 100644 index 0000000..d28a8b1 --- /dev/null +++ b/lens-protocol/modules/helpers/types.ts @@ -0,0 +1,68 @@ +export interface SymbolMap { + [symbol: string]: T; +} + +export type eNetwork = eEthereumNetwork | ePolygonNetwork | eXDaiNetwork; + +export enum eEthereumNetwork { + kovan = 'kovan', + ropsten = 'ropsten', + main = 'main', + hardhat = 'hardhat', + tenderlyMain = 'tenderlyMain', + harhatevm = 'harhatevm', +} + +export enum ePolygonNetwork { + matic = 'matic', + mumbai = 'mumbai', +} + +export enum eXDaiNetwork { + xdai = 'xdai', +} + +export enum EthereumNetworkNames { + kovan = 'kovan', + ropsten = 'ropsten', + main = 'main', + matic = 'matic', + mumbai = 'mumbai', + xdai = 'xdai', +} + +export type tEthereumAddress = string; +export type tStringTokenBigUnits = string; // 1 ETH, or 10e6 USDC or 10e18 DAI +export type tStringTokenSmallUnits = string; // 1 wei, or 1 basic unit of USDC, or 1 basic unit of DAI + +export type iParamsPerNetwork = + | iEthereumParamsPerNetwork + | iPolygonParamsPerNetwork + | iXDaiParamsPerNetwork; + +export interface iParamsPerNetworkAll + extends iEthereumParamsPerNetwork, + iPolygonParamsPerNetwork, + iXDaiParamsPerNetwork {} + +export interface iEthereumParamsPerNetwork { + [eEthereumNetwork.harhatevm]: eNetwork; + [eEthereumNetwork.kovan]: eNetwork; + [eEthereumNetwork.ropsten]: eNetwork; + [eEthereumNetwork.main]: eNetwork; + [eEthereumNetwork.hardhat]: eNetwork; + [eEthereumNetwork.tenderlyMain]: eNetwork; +} + +export interface iPolygonParamsPerNetwork { + [ePolygonNetwork.matic]: T; + [ePolygonNetwork.mumbai]: T; +} + +export interface iXDaiParamsPerNetwork { + [eXDaiNetwork.xdai]: T; +} + +export interface ObjectString { + [key: string]: string; +} diff --git a/lens-protocol/modules/helpers/wallet-helpers.ts b/lens-protocol/modules/helpers/wallet-helpers.ts new file mode 100644 index 0000000..42a12d0 --- /dev/null +++ b/lens-protocol/modules/helpers/wallet-helpers.ts @@ -0,0 +1,20 @@ +import { Wallet, Signer } from 'ethers'; +import { DefenderRelaySigner, DefenderRelayProvider } from 'defender-relay-client/lib/ethers'; +import dotenv from 'dotenv'; + +dotenv.config({ path: '../.env' }); + +const PRIVATE_KEY = process.env.PRIVATE_KEY || ''; +const MNEMONIC = process.env.MNEMONIC || ''; +const DEFENDER_API_KEY = process.env.DEFENDER_API_KEY || ''; +const DEFENDER_SECRET_KEY = process.env.DEFENDER_SECRET_KEY || ''; + +export const getPrivateKeyWallet = (): Signer => new Wallet(PRIVATE_KEY); + +export const getMnemonicWallet = (): Signer => Wallet.fromMnemonic(MNEMONIC); + +export const getDefenderSigner = (): Signer => { + const credentials = { apiKey: DEFENDER_API_KEY, apiSecret: DEFENDER_SECRET_KEY }; + const provider = new DefenderRelayProvider(credentials); + return new DefenderRelaySigner(credentials, provider, { speed: 'fast' }); +}; diff --git a/lens-protocol/modules/lib/forge-std/.github/workflows/ci.yml b/lens-protocol/modules/lib/forge-std/.github/workflows/ci.yml new file mode 100644 index 0000000..96b2336 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/.github/workflows/ci.yml @@ -0,0 +1,92 @@ +name: CI + +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Print forge version + run: forge --version + + # Backwards compatibility checks. + - name: Check compatibility with 0.8.0 + if: always() + run: forge build --skip test --use solc:0.8.0 + + - name: Check compatibility with 0.7.6 + if: always() + run: forge build --skip test --use solc:0.7.6 + + - name: Check compatibility with 0.7.0 + if: always() + run: forge build --skip test --use solc:0.7.0 + + - name: Check compatibility with 0.6.12 + if: always() + run: forge build --skip test --use solc:0.6.12 + + - name: Check compatibility with 0.6.2 + if: always() + run: forge build --skip test --use solc:0.6.2 + + # via-ir compilation time checks. + - name: Measure compilation time of Test with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationTest.sol --use solc:0.8.17 --via-ir + + - name: Measure compilation time of TestBase with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationTestBase.sol --use solc:0.8.17 --via-ir + + - name: Measure compilation time of Script with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationScript.sol --use solc:0.8.17 --via-ir + + - name: Measure compilation time of ScriptBase with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationScriptBase.sol --use solc:0.8.17 --via-ir + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Print forge version + run: forge --version + + - name: Run tests + run: forge test -vvv + + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Print forge version + run: forge --version + + - name: Check formatting + run: forge fmt --check diff --git a/lens-protocol/modules/lib/forge-std/.github/workflows/sync.yml b/lens-protocol/modules/lib/forge-std/.github/workflows/sync.yml new file mode 100644 index 0000000..5a9e9d5 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/.github/workflows/sync.yml @@ -0,0 +1,29 @@ +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/lens-protocol/modules/lib/forge-std/.gitignore b/lens-protocol/modules/lib/forge-std/.gitignore new file mode 100644 index 0000000..756106d --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/.gitignore @@ -0,0 +1,4 @@ +cache/ +out/ +.vscode +.idea diff --git a/lens-protocol/modules/lib/forge-std/.gitmodules b/lens-protocol/modules/lib/forge-std/.gitmodules new file mode 100644 index 0000000..e124719 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/ds-test"] + path = lib/ds-test + url = https://github.com/dapphub/ds-test diff --git a/lens-protocol/modules/lib/forge-std/LICENSE-APACHE b/lens-protocol/modules/lib/forge-std/LICENSE-APACHE new file mode 100644 index 0000000..cf01a49 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/LICENSE-APACHE @@ -0,0 +1,203 @@ +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/lens-protocol/modules/lib/forge-std/LICENSE-MIT b/lens-protocol/modules/lib/forge-std/LICENSE-MIT new file mode 100644 index 0000000..28f9830 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/LICENSE-MIT @@ -0,0 +1,25 @@ +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/lens-protocol/modules/lib/forge-std/README.md b/lens-protocol/modules/lib/forge-std/README.md new file mode 100644 index 0000000..8494a7d --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/README.md @@ -0,0 +1,250 @@ +# 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/lens-protocol/modules/lib/forge-std/foundry.toml b/lens-protocol/modules/lib/forge-std/foundry.toml new file mode 100644 index 0000000..f9679ee --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/foundry.toml @@ -0,0 +1,21 @@ +[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/lens-protocol/modules/lib/forge-std/lib/ds-test/.github/workflows/build.yml b/lens-protocol/modules/lib/forge-std/lib/ds-test/.github/workflows/build.yml new file mode 100644 index 0000000..d2ff97d --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/lib/ds-test/.github/workflows/build.yml @@ -0,0 +1,41 @@ +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/lens-protocol/modules/lib/forge-std/lib/ds-test/.gitignore b/lens-protocol/modules/lib/forge-std/lib/ds-test/.gitignore new file mode 100644 index 0000000..462a994 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/lib/ds-test/.gitignore @@ -0,0 +1,4 @@ +/.dapple +/build +/out +/cache/ diff --git a/lens-protocol/modules/lib/forge-std/lib/ds-test/LICENSE b/lens-protocol/modules/lib/forge-std/lib/ds-test/LICENSE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/lib/ds-test/LICENSE @@ -0,0 +1,674 @@ + 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/lens-protocol/modules/lib/forge-std/lib/ds-test/Makefile b/lens-protocol/modules/lib/forge-std/lib/ds-test/Makefile new file mode 100644 index 0000000..661dac4 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/lib/ds-test/Makefile @@ -0,0 +1,14 @@ +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/lens-protocol/modules/lib/forge-std/lib/ds-test/default.nix b/lens-protocol/modules/lib/forge-std/lib/ds-test/default.nix new file mode 100644 index 0000000..cf65419 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/lib/ds-test/default.nix @@ -0,0 +1,4 @@ +{ solidityPackage, dappsys }: solidityPackage { + name = "ds-test"; + src = ./src; +} diff --git a/lens-protocol/modules/lib/forge-std/lib/ds-test/demo/demo.sol b/lens-protocol/modules/lib/forge-std/lib/ds-test/demo/demo.sol new file mode 100644 index 0000000..f3bb48e --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/lib/ds-test/demo/demo.sol @@ -0,0 +1,222 @@ +// 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/lens-protocol/modules/lib/forge-std/lib/ds-test/package.json b/lens-protocol/modules/lib/forge-std/lib/ds-test/package.json new file mode 100644 index 0000000..4802ada --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/lib/ds-test/package.json @@ -0,0 +1,15 @@ +{ + "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/lens-protocol/modules/lib/forge-std/lib/ds-test/src/test.sol b/lens-protocol/modules/lib/forge-std/lib/ds-test/src/test.sol new file mode 100644 index 0000000..2bf3375 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/lib/ds-test/src/test.sol @@ -0,0 +1,592 @@ +// 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/lens-protocol/modules/lib/forge-std/lib/ds-test/src/test.t.sol b/lens-protocol/modules/lib/forge-std/lib/ds-test/src/test.t.sol new file mode 100644 index 0000000..d277a30 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/lib/ds-test/src/test.t.sol @@ -0,0 +1,417 @@ +// 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/lens-protocol/modules/lib/forge-std/package.json b/lens-protocol/modules/lib/forge-std/package.json new file mode 100644 index 0000000..f39bb39 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/package.json @@ -0,0 +1,16 @@ +{ + "name": "forge-std", + "version": "1.5.6", + "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", + "homepage": "https://book.getfoundry.sh/forge/forge-std", + "bugs": "https://github.com/foundry-rs/forge-std/issues", + "license": "(Apache-2.0 OR MIT)", + "author": "Contributors to Forge Standard Library", + "files": [ + "src/**/*" + ], + "repository": { + "type": "git", + "url": "https://github.com/foundry-rs/forge-std.git" + } +} diff --git a/lens-protocol/modules/lib/forge-std/src/Base.sol b/lens-protocol/modules/lib/forge-std/src/Base.sol new file mode 100644 index 0000000..851ac0c --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/Base.sol @@ -0,0 +1,35 @@ +// 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/lens-protocol/modules/lib/forge-std/src/Script.sol b/lens-protocol/modules/lib/forge-std/src/Script.sol new file mode 100644 index 0000000..bffccad --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/Script.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +// 💬 ABOUT +// Standard Library's default Script. + +// 🧩 MODULES +import {ScriptBase} from "./Base.sol"; +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheatsSafe} from "./StdCheats.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {VmSafe} from "./Vm.sol"; + +// 📦 BOILERPLATE +import {ScriptBase} from "./Base.sol"; + +// ⭐️ SCRIPT +abstract contract Script is StdChains, StdCheatsSafe, StdUtils, ScriptBase { + // Note: IS_SCRIPT() must return true. + bool public IS_SCRIPT = true; +} diff --git a/lens-protocol/modules/lib/forge-std/src/StdAssertions.sol b/lens-protocol/modules/lib/forge-std/src/StdAssertions.sol new file mode 100644 index 0000000..2778b3a --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdAssertions.sol @@ -0,0 +1,376 @@ +// 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/lens-protocol/modules/lib/forge-std/src/StdChains.sol b/lens-protocol/modules/lib/forge-std/src/StdChains.sol new file mode 100644 index 0000000..f97637f --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdChains.sol @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +/** + * StdChains provides information about EVM compatible chains that can be used in scripts/tests. + * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are + * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of + * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the + * alias used in this contract, which can be found as the first argument to the + * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. + * + * There are two main ways to use this contract: + * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or + * `setChain(string memory chainAlias, Chain memory chain)` + * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. + * + * The first time either of those are used, chains are initialized with the default set of RPC URLs. + * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in + * `defaultRpcUrls`. + * + * The `setChain` function is straightforward, and it simply saves off the given chain data. + * + * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say + * we want to retrieve the RPC URL for `mainnet`: + * - If you have specified data with `setChain`, it will return that. + * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it + * is valid (e.g. a URL is specified, or an environment variable is given and exists). + * - If neither of the above conditions is met, the default data is returned. + * + * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults. + */ +abstract contract StdChains { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + bool private stdChainsInitialized; + + struct ChainData { + string name; + uint256 chainId; + string rpcUrl; + } + + struct Chain { + // The chain name. + string name; + // The chain's Chain ID. + uint256 chainId; + // The chain's alias. (i.e. what gets specified in `foundry.toml`). + string chainAlias; + // A default RPC endpoint for this chain. + // NOTE: This default RPC URL is included for convenience to facilitate quick tests and + // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy + // usage as you will be throttled and this is a disservice to others who need this endpoint. + string rpcUrl; + } + + // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data. + mapping(string => Chain) private chains; + // Maps from the chain's alias to it's default RPC URL. + mapping(string => string) private defaultRpcUrls; + // Maps from a chain ID to it's alias. + mapping(uint256 => string) private idToAlias; + + bool private fallbackToDefaultRpcUrls = true; + + // The RPC URL will be fetched from config or defaultRpcUrls if possible. + function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) { + require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string."); + + initializeStdChains(); + chain = chains[chainAlias]; + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + function getChain(uint256 chainId) internal virtual returns (Chain memory chain) { + require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0."); + initializeStdChains(); + string memory chainAlias = idToAlias[chainId]; + + chain = chains[chainAlias]; + + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, ChainData memory chain) internal virtual { + require( + bytes(chainAlias).length != 0, + "StdChains setChain(string,ChainData): Chain alias cannot be the empty string." + ); + + require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0."); + + initializeStdChains(); + string memory foundAlias = idToAlias[chain.chainId]; + + require( + bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)), + string( + abi.encodePacked( + "StdChains setChain(string,ChainData): Chain ID ", + vm.toString(chain.chainId), + " already used by \"", + foundAlias, + "\"." + ) + ) + ); + + uint256 oldChainId = chains[chainAlias].chainId; + delete idToAlias[oldChainId]; + + chains[chainAlias] = + Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl}); + idToAlias[chain.chainId] = chainAlias; + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, Chain memory chain) internal virtual { + setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl})); + } + + function _toUpper(string memory str) private pure returns (string memory) { + bytes memory strb = bytes(str); + bytes memory copy = new bytes(strb.length); + for (uint256 i = 0; i < strb.length; i++) { + bytes1 b = strb[i]; + if (b >= 0x61 && b <= 0x7A) { + copy[i] = bytes1(uint8(b) - 32); + } else { + copy[i] = b; + } + } + return string(copy); + } + + // lookup rpcUrl, in descending order of priority: + // current -> config (foundry.toml) -> environment variable -> default + function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) { + if (bytes(chain.rpcUrl).length == 0) { + try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) { + chain.rpcUrl = configRpcUrl; + } catch (bytes memory err) { + string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL")); + if (fallbackToDefaultRpcUrls) { + chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]); + } else { + chain.rpcUrl = vm.envString(envName); + } + // distinguish 'not found' from 'cannot read' + bytes memory notFoundError = + abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); + if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) { + /// @solidity memory-safe-assembly + assembly { + revert(add(32, err), mload(err)) + } + } + } + } + return chain; + } + + function setFallbackToDefaultRpcUrls(bool useDefault) internal { + fallbackToDefaultRpcUrls = useDefault; + } + + function initializeStdChains() private { + if (stdChainsInitialized) return; + + stdChainsInitialized = true; + + // If adding an RPC here, make sure to test the default RPC URL in `testRpcs` + setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); + setChainWithDefaultRpcUrl( + "mainnet", ChainData("Mainnet", 1, "https://mainnet.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl( + "goerli", ChainData("Goerli", 5, "https://goerli.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl( + "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); + setChainWithDefaultRpcUrl("optimism_goerli", ChainData("Optimism Goerli", 420, "https://goerli.optimism.io")); + setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl( + "arbitrum_one_goerli", ChainData("Arbitrum One Goerli", 421613, "https://goerli-rollup.arbitrum.io/rpc") + ); + setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com")); + setChainWithDefaultRpcUrl( + "polygon_mumbai", ChainData("Polygon Mumbai", 80001, "https://rpc-mumbai.maticvigil.com") + ); + setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc")); + setChainWithDefaultRpcUrl( + "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain_testnet", + ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel") + ); + setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com")); + } + + // set chain info, with priority to chainAlias' rpc url in foundry.toml + function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private { + string memory rpcUrl = chain.rpcUrl; + defaultRpcUrls[chainAlias] = rpcUrl; + chain.rpcUrl = ""; + setChain(chainAlias, chain); + chain.rpcUrl = rpcUrl; // restore argument + } +} diff --git a/lens-protocol/modules/lib/forge-std/src/StdCheats.sol b/lens-protocol/modules/lib/forge-std/src/StdCheats.sol new file mode 100644 index 0000000..c1750c6 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdCheats.sol @@ -0,0 +1,676 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {Vm} from "./Vm.sol"; +import {console2} from "./console2.sol"; + +abstract contract StdCheatsSafe { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + bool private gasMeteringOff; + + // Data structures to parse Transaction objects from the broadcast artifact + // that conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawTx1559 { + string[] arguments; + address contractAddress; + string contractName; + // json value name = function + string functionSig; + bytes32 hash; + // json value name = tx + RawTx1559Detail txDetail; + // json value name = type + string opcode; + } + + struct RawTx1559Detail { + AccessList[] accessList; + bytes data; + address from; + bytes gas; + bytes nonce; + address to; + bytes txType; + bytes value; + } + + struct Tx1559 { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + bytes32 hash; + Tx1559Detail txDetail; + string opcode; + } + + struct Tx1559Detail { + AccessList[] accessList; + bytes data; + address from; + uint256 gas; + uint256 nonce; + address to; + uint256 txType; + uint256 value; + } + + // Data structures to parse Transaction objects from the broadcast artifact + // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct TxLegacy { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + string hash; + string opcode; + TxDetailLegacy transaction; + } + + struct TxDetailLegacy { + AccessList[] accessList; + uint256 chainId; + bytes data; + address from; + uint256 gas; + uint256 gasPrice; + bytes32 hash; + uint256 nonce; + bytes1 opcode; + bytes32 r; + bytes32 s; + uint256 txType; + address to; + uint8 v; + uint256 value; + } + + struct AccessList { + address accessAddress; + bytes32[] storageKeys; + } + + // Data structures to parse Receipt objects from the broadcast artifact. + // The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawReceipt { + bytes32 blockHash; + bytes blockNumber; + address contractAddress; + bytes cumulativeGasUsed; + bytes effectiveGasPrice; + address from; + bytes gasUsed; + RawReceiptLog[] logs; + bytes logsBloom; + bytes status; + address to; + bytes32 transactionHash; + bytes transactionIndex; + } + + struct Receipt { + bytes32 blockHash; + uint256 blockNumber; + address contractAddress; + uint256 cumulativeGasUsed; + uint256 effectiveGasPrice; + address from; + uint256 gasUsed; + ReceiptLog[] logs; + bytes logsBloom; + uint256 status; + address to; + bytes32 transactionHash; + uint256 transactionIndex; + } + + // Data structures to parse the entire broadcast artifact, assuming the + // transactions conform to EIP1559. + + struct EIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + Receipt[] receipts; + uint256 timestamp; + Tx1559[] transactions; + TxReturn[] txReturns; + } + + struct RawEIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + RawReceipt[] receipts; + TxReturn[] txReturns; + uint256 timestamp; + RawTx1559[] transactions; + } + + struct RawReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + bytes blockNumber; + bytes data; + bytes logIndex; + bool removed; + bytes32[] topics; + bytes32 transactionHash; + bytes transactionIndex; + bytes transactionLogIndex; + } + + struct ReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + uint256 blockNumber; + bytes data; + uint256 logIndex; + bytes32[] topics; + uint256 transactionIndex; + uint256 transactionLogIndex; + bool removed; + } + + struct TxReturn { + string internalType; + string value; + } + + struct Account { + address addr; + uint256 key; + } + + // Checks that `addr` is not blacklisted by token contracts that have a blacklist. + function assumeNoBlacklisted(address token, address addr) internal virtual { + // Nothing to check if `token` is not a contract. + uint256 tokenCodeSize; + assembly { + tokenCodeSize := extcodesize(token) + } + require(tokenCodeSize > 0, "StdCheats assumeNoBlacklisted(address,address): Token address is not a contract."); + + bool success; + bytes memory returnData; + + // 4-byte selector for `isBlacklisted(address)`, used by USDC. + (success, returnData) = token.staticcall(abi.encodeWithSelector(0xfe575a87, addr)); + vm.assume(!success || abi.decode(returnData, (bool)) == false); + + // 4-byte selector for `isBlackListed(address)`, used by USDT. + (success, returnData) = token.staticcall(abi.encodeWithSelector(0xe47d6060, addr)); + vm.assume(!success || abi.decode(returnData, (bool)) == false); + } + + function assumeNoPrecompiles(address addr) internal virtual { + // Assembly required since `block.chainid` was introduced in 0.8.0. + uint256 chainId; + assembly { + chainId := chainid() + } + assumeNoPrecompiles(addr, chainId); + } + + function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual { + // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific + // address), but the same rationale for excluding them applies so we include those too. + + // These should be present on all EVM-compatible chains. + vm.assume(addr < address(0x1) || addr > address(0x9)); + + // forgefmt: disable-start + if (chainId == 10 || chainId == 420) { + // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 + vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); + } else if (chainId == 42161 || chainId == 421613) { + // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains + vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); + } else if (chainId == 43114 || chainId == 43113) { + // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 + vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); + vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); + vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); + } + // forgefmt: disable-end + } + + function readEIP1559ScriptArtifact(string memory path) + internal + view + virtual + returns (EIP1559ScriptArtifact memory) + { + string memory data = vm.readFile(path); + bytes memory parsedData = vm.parseJson(data); + RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); + EIP1559ScriptArtifact memory artifact; + artifact.libraries = rawArtifact.libraries; + artifact.path = rawArtifact.path; + artifact.timestamp = rawArtifact.timestamp; + artifact.pending = rawArtifact.pending; + artifact.txReturns = rawArtifact.txReturns; + artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); + artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); + return artifact; + } + + function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { + Tx1559[] memory txs = new Tx1559[](rawTxs.length); + for (uint256 i; i < rawTxs.length; i++) { + txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); + } + return txs; + } + + function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { + Tx1559 memory transaction; + transaction.arguments = rawTx.arguments; + transaction.contractName = rawTx.contractName; + transaction.functionSig = rawTx.functionSig; + transaction.hash = rawTx.hash; + transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); + transaction.opcode = rawTx.opcode; + return transaction; + } + + function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) + internal + pure + virtual + returns (Tx1559Detail memory) + { + Tx1559Detail memory txDetail; + txDetail.data = rawDetail.data; + txDetail.from = rawDetail.from; + txDetail.to = rawDetail.to; + txDetail.nonce = _bytesToUint(rawDetail.nonce); + txDetail.txType = _bytesToUint(rawDetail.txType); + txDetail.value = _bytesToUint(rawDetail.value); + txDetail.gas = _bytesToUint(rawDetail.gas); + txDetail.accessList = rawDetail.accessList; + return txDetail; + } + + function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); + RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); + return rawToConvertedEIPTx1559s(rawTxs); + } + + function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); + return rawToConvertedEIPTx1559(rawTx); + } + + // Analogous to readTransactions, but for receipts. + function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); + RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); + return rawToConvertedReceipts(rawReceipts); + } + + function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); + return rawToConvertedReceipt(rawReceipt); + } + + function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { + Receipt[] memory receipts = new Receipt[](rawReceipts.length); + for (uint256 i; i < rawReceipts.length; i++) { + receipts[i] = rawToConvertedReceipt(rawReceipts[i]); + } + return receipts; + } + + function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { + Receipt memory receipt; + receipt.blockHash = rawReceipt.blockHash; + receipt.to = rawReceipt.to; + receipt.from = rawReceipt.from; + receipt.contractAddress = rawReceipt.contractAddress; + receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice); + receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed); + receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed); + receipt.status = _bytesToUint(rawReceipt.status); + receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex); + receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber); + receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); + receipt.logsBloom = rawReceipt.logsBloom; + receipt.transactionHash = rawReceipt.transactionHash; + return receipt; + } + + function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) + internal + pure + virtual + returns (ReceiptLog[] memory) + { + ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); + for (uint256 i; i < rawLogs.length; i++) { + logs[i].logAddress = rawLogs[i].logAddress; + logs[i].blockHash = rawLogs[i].blockHash; + logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber); + logs[i].data = rawLogs[i].data; + logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex); + logs[i].topics = rawLogs[i].topics; + logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex); + logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex); + logs[i].removed = rawLogs[i].removed; + } + return logs; + } + + // Deploy a contract by fetching the contract bytecode from + // the artifacts directory + // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` + function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); + } + + function deployCode(string memory what) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); + } + + /// @dev deploy contract with value on construction + function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); + } + + function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); + } + + // creates a labeled address and the corresponding private key + function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { + privateKey = uint256(keccak256(abi.encodePacked(name))); + addr = vm.addr(privateKey); + vm.label(addr, name); + } + + // creates a labeled address + function makeAddr(string memory name) internal virtual returns (address addr) { + (addr,) = makeAddrAndKey(name); + } + + // Destroys an account immediately, sending the balance to beneficiary. + // Destroying means: balance will be zero, code will be empty, and nonce will be 0 + // This is similar to selfdestruct but not identical: selfdestruct destroys code and nonce + // only after tx ends, this will run immediately. + function destroyAccount(address who, address beneficiary) internal virtual { + uint256 currBalance = who.balance; + vm.etch(who, abi.encode()); + vm.deal(who, 0); + vm.resetNonce(who); + + uint256 beneficiaryBalance = beneficiary.balance; + vm.deal(beneficiary, currBalance + beneficiaryBalance); + } + + // creates a struct containing both a labeled address and the corresponding private key + function makeAccount(string memory name) internal virtual returns (Account memory account) { + (account.addr, account.key) = makeAddrAndKey(name); + } + + function deriveRememberKey(string memory mnemonic, uint32 index) + internal + virtual + returns (address who, uint256 privateKey) + { + privateKey = vm.deriveKey(mnemonic, index); + who = vm.rememberKey(privateKey); + } + + function _bytesToUint(bytes memory b) private pure returns (uint256) { + require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + function isFork() internal view virtual returns (bool status) { + try vm.activeFork() { + status = true; + } catch (bytes memory) {} + } + + modifier skipWhenForking() { + if (!isFork()) { + _; + } + } + + modifier skipWhenNotForking() { + if (isFork()) { + _; + } + } + + modifier noGasMetering() { + vm.pauseGasMetering(); + // To prevent turning gas monitoring back on with nested functions that use this modifier, + // we check if gasMetering started in the off position. If it did, we don't want to turn + // it back on until we exit the top level function that used the modifier + // + // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well. + // funcA will have `gasStartedOff` as false, funcB will have it as true, + // so we only turn metering back on at the end of the funcA + bool gasStartedOff = gasMeteringOff; + gasMeteringOff = true; + + _; + + // if gas metering was on when this modifier was called, turn it back on at the end + if (!gasStartedOff) { + gasMeteringOff = false; + vm.resumeGasMetering(); + } + } + + // a cheat for fuzzing addresses that are payable only + // see https://github.com/foundry-rs/foundry/issues/3631 + function assumePayable(address addr) internal virtual { + (bool success,) = payable(addr).call{value: 0}(""); + vm.assume(success); + } +} + +// Wrappers around cheatcodes to avoid footguns +abstract contract StdCheats is StdCheatsSafe { + using stdStorage for StdStorage; + + StdStorage private stdstore; + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + // Skip forward or rewind time by the specified number of seconds + function skip(uint256 time) internal virtual { + vm.warp(block.timestamp + time); + } + + function rewind(uint256 time) internal virtual { + vm.warp(block.timestamp - time); + } + + // Setup a prank from an address that has some ether + function hoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender); + } + + function hoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender); + } + + function hoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender, origin); + } + + function hoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender, origin); + } + + // Start perpetual prank from an address that has some ether + function startHoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender); + } + + function startHoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender); + } + + // Start perpetual prank from an address that has some ether + // tx.origin is set to the origin parameter + function startHoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender, origin); + } + + function startHoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender, origin); + } + + function changePrank(address msgSender) internal virtual { + vm.stopPrank(); + vm.startPrank(msgSender); + } + + function changePrank(address msgSender, address txOrigin) internal virtual { + vm.stopPrank(); + vm.startPrank(msgSender, txOrigin); + } + + // The same as Vm's `deal` + // Use the alternative signature for ERC20 tokens + function deal(address to, uint256 give) internal virtual { + vm.deal(to, give); + } + + // Set the balance of an account for any ERC20 token + // Use the alternative signature to update `totalSupply` + function deal(address token, address to, uint256 give) internal virtual { + deal(token, to, give, false); + } + + // Set the balance of an account for any ERC1155 token + // Use the alternative signature to update `totalSupply` + function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual { + dealERC1155(token, to, id, give, false); + } + + function deal(address token, address to, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0x18160ddd)); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0x18160ddd).checked_write(totSup); + } + } + + function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x00fdd58e, to, id)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0xbd85b039, id)); + require( + totSupData.length != 0, + "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply." + ); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup); + } + } + + function dealERC721(address token, address to, uint256 id) internal virtual { + // check if token id is already minted and the actual owner. + (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id)); + require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted."); + + // get owner current balance + (, bytes memory fromBalData) = + token.staticcall(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address)))); + uint256 fromPrevBal = abi.decode(fromBalData, (uint256)); + + // get new user current balance + (, bytes memory toBalData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); + uint256 toPrevBal = abi.decode(toBalData, (uint256)); + + // update balances + stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal); + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal); + + // update owner + stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to); + } +} diff --git a/lens-protocol/modules/lib/forge-std/src/StdError.sol b/lens-protocol/modules/lib/forge-std/src/StdError.sol new file mode 100644 index 0000000..a302191 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdError.sol @@ -0,0 +1,15 @@ +// 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/lens-protocol/modules/lib/forge-std/src/StdInvariant.sol b/lens-protocol/modules/lib/forge-std/src/StdInvariant.sol new file mode 100644 index 0000000..efa1129 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdInvariant.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +contract StdInvariant { + struct FuzzSelector { + address addr; + bytes4[] selectors; + } + + address[] private _excludedContracts; + address[] private _excludedSenders; + address[] private _targetedContracts; + address[] private _targetedSenders; + + string[] private _excludedArtifacts; + string[] private _targetedArtifacts; + + FuzzSelector[] private _targetedArtifactSelectors; + FuzzSelector[] private _targetedSelectors; + + // Functions for users: + // These are intended to be called in tests. + + function excludeContract(address newExcludedContract_) internal { + _excludedContracts.push(newExcludedContract_); + } + + function excludeSender(address newExcludedSender_) internal { + _excludedSenders.push(newExcludedSender_); + } + + function excludeArtifact(string memory newExcludedArtifact_) internal { + _excludedArtifacts.push(newExcludedArtifact_); + } + + function targetArtifact(string memory newTargetedArtifact_) internal { + _targetedArtifacts.push(newTargetedArtifact_); + } + + function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal { + _targetedArtifactSelectors.push(newTargetedArtifactSelector_); + } + + function targetContract(address newTargetedContract_) internal { + _targetedContracts.push(newTargetedContract_); + } + + function targetSelector(FuzzSelector memory newTargetedSelector_) internal { + _targetedSelectors.push(newTargetedSelector_); + } + + function targetSender(address newTargetedSender_) internal { + _targetedSenders.push(newTargetedSender_); + } + + // Functions for forge: + // These are called by forge to run invariant tests and don't need to be called in tests. + + function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) { + excludedArtifacts_ = _excludedArtifacts; + } + + function excludeContracts() public view returns (address[] memory excludedContracts_) { + excludedContracts_ = _excludedContracts; + } + + function excludeSenders() public view returns (address[] memory excludedSenders_) { + excludedSenders_ = _excludedSenders; + } + + function targetArtifacts() public view returns (string[] memory targetedArtifacts_) { + targetedArtifacts_ = _targetedArtifacts; + } + + function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) { + targetedArtifactSelectors_ = _targetedArtifactSelectors; + } + + function targetContracts() public view returns (address[] memory targetedContracts_) { + targetedContracts_ = _targetedContracts; + } + + function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) { + targetedSelectors_ = _targetedSelectors; + } + + function targetSenders() public view returns (address[] memory targetedSenders_) { + targetedSenders_ = _targetedSenders; + } +} diff --git a/lens-protocol/modules/lib/forge-std/src/StdJson.sol b/lens-protocol/modules/lib/forge-std/src/StdJson.sol new file mode 100644 index 0000000..014e6b1 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdJson.sol @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +// Helpers for parsing and writing JSON files +// To parse: +// ``` +// using stdJson for string; +// string memory json = vm.readFile("some_peth"); +// json.parseUint(""); +// ``` +// To write: +// ``` +// using stdJson for string; +// string memory json = "deploymentArtifact"; +// Contract contract = new Contract(); +// json.serialize("contractAddress", address(contract)); +// json = json.serialize("deploymentTimes", uint(1)); +// // store the stringified JSON to the 'json' variable we have been using as a key +// // as we won't need it any longer +// string memory json2 = "finalArtifact"; +// string memory final = json2.serialize("depArtifact", json); +// final.write(""); +// ``` + +library stdJson { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) { + return vm.parseJson(json, key); + } + + function readUint(string memory json, string memory key) internal returns (uint256) { + return vm.parseJsonUint(json, key); + } + + function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) { + return vm.parseJsonUintArray(json, key); + } + + function readInt(string memory json, string memory key) internal returns (int256) { + return vm.parseJsonInt(json, key); + } + + function readIntArray(string memory json, string memory key) internal returns (int256[] memory) { + return vm.parseJsonIntArray(json, key); + } + + function readBytes32(string memory json, string memory key) internal returns (bytes32) { + return vm.parseJsonBytes32(json, key); + } + + function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) { + return vm.parseJsonBytes32Array(json, key); + } + + function readString(string memory json, string memory key) internal returns (string memory) { + return vm.parseJsonString(json, key); + } + + function readStringArray(string memory json, string memory key) internal returns (string[] memory) { + return vm.parseJsonStringArray(json, key); + } + + function readAddress(string memory json, string memory key) internal returns (address) { + return vm.parseJsonAddress(json, key); + } + + function readAddressArray(string memory json, string memory key) internal returns (address[] memory) { + return vm.parseJsonAddressArray(json, key); + } + + function readBool(string memory json, string memory key) internal returns (bool) { + return vm.parseJsonBool(json, key); + } + + function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) { + return vm.parseJsonBoolArray(json, key); + } + + function readBytes(string memory json, string memory key) internal returns (bytes memory) { + return vm.parseJsonBytes(json, key); + } + + function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) { + return vm.parseJsonBytesArray(json, key); + } + + function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bool[] memory value) + internal + returns (string memory) + { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256[] memory value) + internal + returns (string memory) + { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256[] memory value) + internal + returns (string memory) + { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address[] memory value) + internal + returns (string memory) + { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string[] memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function write(string memory jsonKey, string memory path) internal { + vm.writeJson(jsonKey, path); + } + + function write(string memory jsonKey, string memory path, string memory valueKey) internal { + vm.writeJson(jsonKey, path, valueKey); + } +} diff --git a/lens-protocol/modules/lib/forge-std/src/StdMath.sol b/lens-protocol/modules/lib/forge-std/src/StdMath.sol new file mode 100644 index 0000000..459523b --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdMath.sol @@ -0,0 +1,43 @@ +// 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/lens-protocol/modules/lib/forge-std/src/StdStorage.sol b/lens-protocol/modules/lib/forge-std/src/StdStorage.sol new file mode 100644 index 0000000..73a5ceb --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdStorage.sol @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {Vm} from "./Vm.sol"; + +struct StdStorage { + mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots; + mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds; + bytes32[] _keys; + bytes4 _sig; + uint256 _depth; + address _target; + bytes32 _set; +} + +library stdStorageSafe { + event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); + event WARNING_UninitedSlot(address who, uint256 slot); + + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return bytes4(keccak256(bytes(sigStr))); + } + + /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against + // slot complexity: + // if flat, will be bytes32(uint256(uint)); + // if map, will be keccak256(abi.encode(key, uint(slot))); + // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); + // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); + function find(StdStorage storage self) internal returns (uint256) { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes32[] memory ins = self._keys; + + // calldata to test against + if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { + return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; + } + bytes memory cald = abi.encodePacked(fsig, flatten(ins)); + vm.record(); + bytes32 fdat; + { + (, bytes memory rdat) = who.staticcall(cald); + fdat = bytesToBytes32(rdat, 32 * field_depth); + } + + (bytes32[] memory reads,) = vm.accesses(address(who)); + if (reads.length == 1) { + bytes32 curr = vm.load(who, reads[0]); + if (curr == bytes32(0)) { + emit WARNING_UninitedSlot(who, uint256(reads[0])); + } + if (fdat != curr) { + require( + false, + "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." + ); + } + emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0])); + self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]); + self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; + } else if (reads.length > 1) { + for (uint256 i = 0; i < reads.length; i++) { + bytes32 prev = vm.load(who, reads[i]); + if (prev == bytes32(0)) { + emit WARNING_UninitedSlot(who, uint256(reads[i])); + } + // store + vm.store(who, reads[i], bytes32(hex"1337")); + bool success; + bytes memory rdat; + { + (success, rdat) = who.staticcall(cald); + fdat = bytesToBytes32(rdat, 32 * field_depth); + } + + if (success && fdat == bytes32(hex"1337")) { + // we found which of the slots is the actual one + emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i])); + self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]); + self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; + vm.store(who, reads[i], prev); + break; + } + vm.store(who, reads[i], prev); + } + } else { + revert("stdStorage find(StdStorage): No storage use detected for target."); + } + + require( + self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))], + "stdStorage find(StdStorage): Slot(s) not found." + ); + + delete self._target; + delete self._sig; + delete self._keys; + delete self._depth; + + return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + self._target = _target; + return self; + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + self._sig = _sig; + return self; + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + self._sig = sigs(_sig); + return self; + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + self._keys.push(bytes32(uint256(uint160(who)))); + return self; + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + self._keys.push(bytes32(amt)); + return self; + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + self._keys.push(key); + return self; + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + self._depth = _depth; + return self; + } + + function read(StdStorage storage self) private returns (bytes memory) { + address t = self._target; + uint256 s = find(self); + return abi.encode(vm.load(t, bytes32(s))); + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return abi.decode(read(self), (bytes32)); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + int256 v = read_int(self); + if (v == 0) return false; + if (v == 1) return true; + revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + } + + function read_address(StdStorage storage self) internal returns (address) { + return abi.decode(read(self), (address)); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return abi.decode(read(self), (uint256)); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return abi.decode(read(self), (int256)); + } + + function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { + bytes32 out; + + uint256 max = b.length > 32 ? 32 : b.length; + for (uint256 i = 0; i < max; i++) { + out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); + } + return out; + } + + function flatten(bytes32[] memory b) private pure returns (bytes memory) { + bytes memory result = new bytes(b.length * 32); + for (uint256 i = 0; i < b.length; i++) { + bytes32 k = b[i]; + /// @solidity memory-safe-assembly + assembly { + mstore(add(result, add(32, mul(32, i))), k) + } + } + + return result; + } +} + +library stdStorage { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return stdStorageSafe.sigs(sigStr); + } + + function find(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.find(self); + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + return stdStorageSafe.target(self, _target); + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, who); + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, amt); + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, key); + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + return stdStorageSafe.depth(self, _depth); + } + + function checked_write(StdStorage storage self, address who) internal { + checked_write(self, bytes32(uint256(uint160(who)))); + } + + function checked_write(StdStorage storage self, uint256 amt) internal { + checked_write(self, bytes32(amt)); + } + + function checked_write(StdStorage storage self, bool write) internal { + bytes32 t; + /// @solidity memory-safe-assembly + assembly { + t := write + } + checked_write(self, t); + } + + function checked_write(StdStorage storage self, bytes32 set) internal { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes32[] memory ins = self._keys; + + bytes memory cald = abi.encodePacked(fsig, flatten(ins)); + if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { + find(self); + } + bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]); + + bytes32 fdat; + { + (, bytes memory rdat) = who.staticcall(cald); + fdat = bytesToBytes32(rdat, 32 * field_depth); + } + bytes32 curr = vm.load(who, slot); + + if (fdat != curr) { + require( + false, + "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." + ); + } + vm.store(who, slot, set); + delete self._target; + delete self._sig; + delete self._keys; + delete self._depth; + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return stdStorageSafe.read_bytes32(self); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + return stdStorageSafe.read_bool(self); + } + + function read_address(StdStorage storage self) internal returns (address) { + return stdStorageSafe.read_address(self); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.read_uint(self); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return stdStorageSafe.read_int(self); + } + + // Private function so needs to be copied over + function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { + bytes32 out; + + uint256 max = b.length > 32 ? 32 : b.length; + for (uint256 i = 0; i < max; i++) { + out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); + } + return out; + } + + // Private function so needs to be copied over + function flatten(bytes32[] memory b) private pure returns (bytes memory) { + bytes memory result = new bytes(b.length * 32); + for (uint256 i = 0; i < b.length; i++) { + bytes32 k = b[i]; + /// @solidity memory-safe-assembly + assembly { + mstore(add(result, add(32, mul(32, i))), k) + } + } + + return result; + } +} diff --git a/lens-protocol/modules/lib/forge-std/src/StdStyle.sol b/lens-protocol/modules/lib/forge-std/src/StdStyle.sol new file mode 100644 index 0000000..46f4e81 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdStyle.sol @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +import {Vm} from "./Vm.sol"; + +library StdStyle { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + string constant RED = "\u001b[91m"; + string constant GREEN = "\u001b[92m"; + string constant YELLOW = "\u001b[93m"; + string constant BLUE = "\u001b[94m"; + string constant MAGENTA = "\u001b[95m"; + string constant CYAN = "\u001b[96m"; + string constant BOLD = "\u001b[1m"; + string constant DIM = "\u001b[2m"; + string constant ITALIC = "\u001b[3m"; + string constant UNDERLINE = "\u001b[4m"; + string constant INVERSE = "\u001b[7m"; + string constant RESET = "\u001b[0m"; + + function styleConcat(string memory style, string memory self) private pure returns (string memory) { + return string(abi.encodePacked(style, self, RESET)); + } + + function red(string memory self) internal pure returns (string memory) { + return styleConcat(RED, self); + } + + function red(uint256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(int256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(address self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(bool self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes(bytes memory self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes32(bytes32 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function green(string memory self) internal pure returns (string memory) { + return styleConcat(GREEN, self); + } + + function green(uint256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(int256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(address self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(bool self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes(bytes memory self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes32(bytes32 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function yellow(string memory self) internal pure returns (string memory) { + return styleConcat(YELLOW, self); + } + + function yellow(uint256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(int256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(address self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(bool self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes(bytes memory self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes32(bytes32 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function blue(string memory self) internal pure returns (string memory) { + return styleConcat(BLUE, self); + } + + function blue(uint256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(int256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(address self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(bool self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes(bytes memory self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes32(bytes32 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function magenta(string memory self) internal pure returns (string memory) { + return styleConcat(MAGENTA, self); + } + + function magenta(uint256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(int256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(address self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(bool self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes(bytes memory self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes32(bytes32 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function cyan(string memory self) internal pure returns (string memory) { + return styleConcat(CYAN, self); + } + + function cyan(uint256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(int256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(address self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(bool self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes(bytes memory self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes32(bytes32 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function bold(string memory self) internal pure returns (string memory) { + return styleConcat(BOLD, self); + } + + function bold(uint256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(int256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(address self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(bool self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes(bytes memory self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes32(bytes32 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function dim(string memory self) internal pure returns (string memory) { + return styleConcat(DIM, self); + } + + function dim(uint256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(int256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(address self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(bool self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes(bytes memory self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes32(bytes32 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function italic(string memory self) internal pure returns (string memory) { + return styleConcat(ITALIC, self); + } + + function italic(uint256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(int256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(address self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(bool self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes(bytes memory self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes32(bytes32 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function underline(string memory self) internal pure returns (string memory) { + return styleConcat(UNDERLINE, self); + } + + function underline(uint256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(int256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(address self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(bool self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes(bytes memory self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes32(bytes32 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function inverse(string memory self) internal pure returns (string memory) { + return styleConcat(INVERSE, self); + } + + function inverse(uint256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(int256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(address self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(bool self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes(bytes memory self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes32(bytes32 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } +} diff --git a/lens-protocol/modules/lib/forge-std/src/StdUtils.sol b/lens-protocol/modules/lib/forge-std/src/StdUtils.sol new file mode 100644 index 0000000..d67025c --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/StdUtils.sol @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {IMulticall3} from "./interfaces/IMulticall3.sol"; +import {VmSafe} from "./Vm.sol"; + +abstract contract StdUtils { + /*////////////////////////////////////////////////////////////////////////// + CONSTANTS + //////////////////////////////////////////////////////////////////////////*/ + + IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; + uint256 private constant INT256_MIN_ABS = + 57896044618658097711785492504343953926634992332820282019728792003956564819968; + uint256 private constant SECP256K1_ORDER = + 115792089237316195423570985008687907852837564279074904382605163141518161494337; + uint256 private constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. + address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + + /*////////////////////////////////////////////////////////////////////////// + INTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { + require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); + // If x is between min and max, return x directly. This is to ensure that dictionary values + // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 + if (x >= min && x <= max) return x; + + uint256 size = max - min + 1; + + // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. + // This helps ensure coverage of the min/max values. + if (x <= 3 && size > x) return min + x; + if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); + + // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. + if (x > max) { + uint256 diff = x - max; + uint256 rem = diff % size; + if (rem == 0) return max; + result = min + rem - 1; + } else if (x < min) { + uint256 diff = min - x; + uint256 rem = diff % size; + if (rem == 0) return min; + result = max - rem + 1; + } + } + + function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) { + result = _bound(x, min, max); + console2_log("Bound Result", result); + } + + function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { + require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min."); + + // Shifting all int256 values to uint256 to use _bound function. The range of two types are: + // int256 : -(2**255) ~ (2**255 - 1) + // uint256: 0 ~ (2**256 - 1) + // So, add 2**255, INT256_MIN_ABS to the integer values. + // + // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow. + // So, use `~uint256(x) + 1` instead. + uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS); + uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS); + uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS); + + uint256 y = _bound(_x, _min, _max); + + // To move it back to int256 value, subtract INT256_MIN_ABS at here. + result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS); + } + + function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) { + result = _bound(x, min, max); + console2_log("Bound result", vm.toString(result)); + } + + function boundPrivateKey(uint256 privateKey) internal view virtual returns (uint256 result) { + result = _bound(privateKey, 1, SECP256K1_ORDER - 1); + } + + function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { + require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce + /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol) + function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { + // forgefmt: disable-start + // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0. + // A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it. + if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))); + if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))); + + // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length. + if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)))); + if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)))); + if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce)))); + // forgefmt: disable-end + + // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp + // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce) + // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) + // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex) + // We assume nobody can have a nonce large enough to require more than 32 bytes. + return addressFromLast20Bytes( + keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))) + ); + } + + function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) + internal + pure + virtual + returns (address) + { + return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash))); + } + + /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer + function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { + return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY); + } + + /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) { + return hashInitCode(creationCode, ""); + } + + /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2 + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + /// @param args the ABI-encoded arguments to the constructor of C + function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(creationCode, args)); + } + + // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses. + function getTokenBalances(address token, address[] memory addresses) + internal + virtual + returns (uint256[] memory balances) + { + uint256 tokenCodeSize; + assembly { + tokenCodeSize := extcodesize(token) + } + require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + + // ABI encode the aggregate call to Multicall3. + uint256 length = addresses.length; + IMulticall3.Call[] memory calls = new IMulticall3.Call[](length); + for (uint256 i = 0; i < length; ++i) { + // 0x70a08231 = bytes4("balanceOf(address)")) + calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))}); + } + + // Make the aggregate call. + (, bytes[] memory returnData) = multicall.aggregate(calls); + + // ABI decode the return data and return the balances. + balances = new uint256[](length); + for (uint256 i = 0; i < length; ++i) { + balances[i] = abi.decode(returnData[i], (uint256)); + } + } + + /*////////////////////////////////////////////////////////////////////////// + PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { + return address(uint160(uint256(bytesValue))); + } + + // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. + + function console2_log(string memory p0, uint256 p1) private view { + (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + status; + } + + function console2_log(string memory p0, string memory p1) private view { + (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,string)", p0, p1)); + status; + } +} diff --git a/lens-protocol/modules/lib/forge-std/src/Test.sol b/lens-protocol/modules/lib/forge-std/src/Test.sol new file mode 100644 index 0000000..9ff5cb8 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/Test.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +// 💬 ABOUT +// Standard Library's default Test + +// 🧩 MODULES +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {StdAssertions} from "./StdAssertions.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheats} from "./StdCheats.sol"; +import {stdError} from "./StdError.sol"; +import {StdInvariant} from "./StdInvariant.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {Vm} from "./Vm.sol"; +import {StdStyle} from "./StdStyle.sol"; + +// 📦 BOILERPLATE +import {TestBase} from "./Base.sol"; +import {DSTest} from "ds-test/test.sol"; + +// ⭐️ TEST +abstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase { +// Note: IS_TEST() must return true. +// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76. +} diff --git a/lens-protocol/modules/lib/forge-std/src/Vm.sol b/lens-protocol/modules/lib/forge-std/src/Vm.sol new file mode 100644 index 0000000..f919e6d --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/Vm.sol @@ -0,0 +1,502 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +// Cheatcodes are marked as view/pure/none using the following rules: +// 0. A call's observable behaviour includes its return value, logs, reverts and state writes, +// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc), +// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`, +// 3. Otherwise you're `pure`. + +interface VmSafe { + struct Log { + bytes32[] topics; + bytes data; + address emitter; + } + + struct Rpc { + string key; + string url; + } + + struct DirEntry { + string errorMessage; + string path; + uint64 depth; + bool isDir; + bool isSymlink; + } + + struct FsMetadata { + bool isDir; + bool isSymlink; + uint256 length; + bool readOnly; + uint256 modified; + uint256 accessed; + uint256 created; + } + + // Loads a storage slot from an address + function load(address target, bytes32 slot) external view returns (bytes32 data); + // Signs data + function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); + // Gets the address for a given private key + function addr(uint256 privateKey) external pure returns (address keyAddr); + // Gets the nonce of an account + function getNonce(address account) external view returns (uint64 nonce); + // Performs a foreign function call via the terminal + function ffi(string[] calldata commandInput) external returns (bytes memory result); + // Sets environment variables + function setEnv(string calldata name, string calldata value) external; + // Reads environment variables, (name) => (value) + function envBool(string calldata name) external view returns (bool value); + function envUint(string calldata name) external view returns (uint256 value); + function envInt(string calldata name) external view returns (int256 value); + function envAddress(string calldata name) external view returns (address value); + function envBytes32(string calldata name) external view returns (bytes32 value); + function envString(string calldata name) external view returns (string memory value); + function envBytes(string calldata name) external view returns (bytes memory value); + // Reads environment variables as arrays + function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); + function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); + function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); + function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); + function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); + function envString(string calldata name, string calldata delim) external view returns (string[] memory value); + function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); + // Read environment variables with default value + function envOr(string calldata name, bool defaultValue) external returns (bool value); + function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value); + function envOr(string calldata name, int256 defaultValue) external returns (int256 value); + function envOr(string calldata name, address defaultValue) external returns (address value); + function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value); + function envOr(string calldata name, string calldata defaultValue) external returns (string memory value); + function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value); + // Read environment variables as arrays with default value + function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) + external + returns (bool[] memory value); + function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) + external + returns (uint256[] memory value); + function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) + external + returns (int256[] memory value); + function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) + external + returns (address[] memory value); + function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) + external + returns (bytes32[] memory value); + function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) + external + returns (string[] memory value); + function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) + external + returns (bytes[] memory value); + // Records all storage reads and writes + function record() external; + // Gets all accessed reads and write slot from a recording session, for a given address + function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); + // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file + function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); + // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file + function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); + // Labels an address in call traces + function label(address account, string calldata newLabel) external; + // Gets the label for the specified address + function getLabel(address account) external returns (string memory label); + // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain + function broadcast() external; + // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain + function broadcast(address signer) external; + // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain + function broadcast(uint256 privateKey) external; + // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain + function startBroadcast() external; + // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain + function startBroadcast(address signer) external; + // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain + function startBroadcast(uint256 privateKey) external; + // Stops collecting onchain transactions + function stopBroadcast() external; + + // Get the path of the current project root. + function projectRoot() external view returns (string memory path); + // Reads the entire content of file to string. `path` is relative to the project root. + function readFile(string calldata path) external view returns (string memory data); + // Reads the entire content of file as binary. `path` is relative to the project root. + function readFileBinary(string calldata path) external view returns (bytes memory data); + // Reads next line of file to string. + function readLine(string calldata path) external view returns (string memory line); + // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. + // `path` is relative to the project root. + function writeFile(string calldata path, string calldata data) external; + // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. + // `path` is relative to the project root. + function writeFileBinary(string calldata path, bytes calldata data) external; + // Writes line to file, creating a file if it does not exist. + // `path` is relative to the project root. + function writeLine(string calldata path, string calldata data) external; + // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. + // `path` is relative to the project root. + function closeFile(string calldata path) external; + // Removes a file from the filesystem. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - `path` points to a directory. + // - The file doesn't exist. + // - The user lacks permissions to remove the file. + // `path` is relative to the project root. + function removeFile(string calldata path) external; + // Creates a new, empty directory at the provided path. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - User lacks permissions to modify `path`. + // - A parent of the given path doesn't exist and `recursive` is false. + // - `path` already exists and `recursive` is false. + // `path` is relative to the project root. + function createDir(string calldata path, bool recursive) external; + // Removes a directory at the provided path. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - `path` doesn't exist. + // - `path` isn't a directory. + // - User lacks permissions to modify `path`. + // - The directory is not empty and `recursive` is false. + // `path` is relative to the project root. + function removeDir(string calldata path, bool recursive) external; + // Reads the directory at the given path recursively, up to `max_depth`. + // `max_depth` defaults to 1, meaning only the direct children of the given directory will be returned. + // Follows symbolic links if `follow_links` is true. + function readDir(string calldata path) external view returns (DirEntry[] memory entries); + function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); + function readDir(string calldata path, uint64 maxDepth, bool followLinks) + external + view + returns (DirEntry[] memory entries); + // Reads a symbolic link, returning the path that the link points to. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - `path` is not a symbolic link. + // - `path` does not exist. + function readLink(string calldata linkPath) external view returns (string memory targetPath); + // Given a path, query the file system to get information about a file, directory, etc. + function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata); + + // Convert values to a string + function toString(address value) external pure returns (string memory stringifiedValue); + function toString(bytes calldata value) external pure returns (string memory stringifiedValue); + function toString(bytes32 value) external pure returns (string memory stringifiedValue); + function toString(bool value) external pure returns (string memory stringifiedValue); + function toString(uint256 value) external pure returns (string memory stringifiedValue); + function toString(int256 value) external pure returns (string memory stringifiedValue); + // Convert values from a string + function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); + function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); + function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); + function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); + function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); + function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); + // Record all the transaction logs + function recordLogs() external; + // Gets all the recorded logs + function getRecordedLogs() external returns (Log[] memory logs); + // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index} + function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); + // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index} + function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) + external + pure + returns (uint256 privateKey); + // Adds a private key to the local forge wallet and returns the address + function rememberKey(uint256 privateKey) external returns (address keyAddr); + // + // parseJson + // + // ---- + // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects + // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in + // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that + // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded + // as tuples, with the attributes in the order in which they are defined. + // For example: json = { 'a': 1, 'b': 0xa4tb......3xs} + // a: uint256 + // b: address + // To decode that json, we need to define a struct or a tuple as follows: + // struct json = { uint256 a; address b; } + // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to + // decode the tuple in that order, and thus fail. + // ---- + // Given a string of JSON, return it as ABI-encoded + function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); + function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); + + // The following parseJson cheatcodes will do type coercion, for the type that they indicate. + // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12' + // and hex numbers '0xEF'. + // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not + // a JSON object. + function parseJsonUint(string calldata, string calldata) external returns (uint256); + function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory); + function parseJsonInt(string calldata, string calldata) external returns (int256); + function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory); + function parseJsonBool(string calldata, string calldata) external returns (bool); + function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory); + function parseJsonAddress(string calldata, string calldata) external returns (address); + function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory); + function parseJsonString(string calldata, string calldata) external returns (string memory); + function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory); + function parseJsonBytes(string calldata, string calldata) external returns (bytes memory); + function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory); + function parseJsonBytes32(string calldata, string calldata) external returns (bytes32); + function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory); + + // Serialize a key and value to a JSON object stored in-memory that can be later written to a file + // It returns the stringified version of the specific JSON file up to that moment. + function serializeBool(string calldata objectKey, string calldata valueKey, bool value) + external + returns (string memory json); + function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) + external + returns (string memory json); + function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) + external + returns (string memory json); + function serializeAddress(string calldata objectKey, string calldata valueKey, address value) + external + returns (string memory json); + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) + external + returns (string memory json); + function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) + external + returns (string memory json); + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) + external + returns (string memory json); + + function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) + external + returns (string memory json); + function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) + external + returns (string memory json); + function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) + external + returns (string memory json); + function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) + external + returns (string memory json); + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) + external + returns (string memory json); + function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) + external + returns (string memory json); + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) + external + returns (string memory json); + + // + // writeJson + // + // ---- + // Write a serialized JSON object to a file. If the file exists, it will be overwritten. + // Let's assume we want to write the following JSON to a file: + // + // { "boolean": true, "number": 342, "object": { "title": "finally json serialization" } } + // + // ``` + // string memory json1 = "some key"; + // vm.serializeBool(json1, "boolean", true); + // vm.serializeBool(json1, "number", uint256(342)); + // json2 = "some other key"; + // string memory output = vm.serializeString(json2, "title", "finally json serialization"); + // string memory finalJson = vm.serialize(json1, "object", output); + // vm.writeJson(finalJson, "./output/example.json"); + // ``` + // The critical insight is that every invocation of serialization will return the stringified version of the JSON + // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version + // to serialize them as values to another JSON object. + // + // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..) + // will find the object in-memory that is keyed by "some key". + function writeJson(string calldata json, string calldata path) external; + // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = + // This is useful to replace a specific value of a JSON file, without having to parse the entire thing + function writeJson(string calldata json, string calldata path, string calldata valueKey) external; + // Returns the RPC url for the given alias + function rpcUrl(string calldata rpcAlias) external view returns (string memory json); + // Returns all rpc urls and their aliases `[alias, url][]` + function rpcUrls() external view returns (string[2][] memory urls); + // Returns all rpc urls and their aliases as structs. + function rpcUrlStructs() external view returns (Rpc[] memory urls); + // If the condition is false, discard this run's fuzz inputs and generate new ones. + function assume(bool condition) external pure; + // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. + function pauseGasMetering() external; + // Resumes gas metering (i.e. gas usage is counted again). Noop if already on. + function resumeGasMetering() external; + // Writes a breakpoint to jump to in the debugger + function breakpoint(string calldata char) external; + // Writes a conditional breakpoint to jump to in the debugger + function breakpoint(string calldata char, bool value) external; +} + +interface Vm is VmSafe { + // Sets block.timestamp + function warp(uint256 newTimestamp) external; + // Sets block.height + function roll(uint256 newHeight) external; + // Sets block.basefee + function fee(uint256 newBasefee) external; + // Sets block.difficulty + // Not available on EVM versions from Paris onwards. Use `prevrandao` instead. + // If used on unsupported EVM versions it will revert. + function difficulty(uint256 newDifficulty) external; + // Sets block.prevrandao + // Not available on EVM versions before Paris. Use `difficulty` instead. + // If used on unsupported EVM versions it will revert. + function prevrandao(bytes32 newPrevrandao) external; + // Sets block.chainid + function chainId(uint256 newChainId) external; + // Sets tx.gasprice + function txGasPrice(uint256 newGasPrice) external; + // Stores a value to an address' storage slot. + function store(address target, bytes32 slot, bytes32 value) external; + // Sets the nonce of an account; must be higher than the current nonce of the account + function setNonce(address account, uint64 newNonce) external; + // Sets the nonce of an account to an arbitrary value + function setNonceUnsafe(address account, uint64 newNonce) external; + // Resets the nonce of an account to 0 for EOAs and 1 for contract accounts + function resetNonce(address account) external; + // Sets the *next* call's msg.sender to be the input address + function prank(address msgSender) external; + // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called + function startPrank(address msgSender) external; + // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input + function prank(address msgSender, address txOrigin) external; + // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input + function startPrank(address msgSender, address txOrigin) external; + // Resets subsequent calls' msg.sender to be `address(this)` + function stopPrank() external; + // Sets an address' balance + function deal(address account, uint256 newBalance) external; + // Sets an address' code + function etch(address target, bytes calldata newRuntimeBytecode) external; + // Expects an error on next call + function expectRevert(bytes calldata revertData) external; + function expectRevert(bytes4 revertData) external; + function expectRevert() external; + + // Prepare an expected log with all four checks enabled. + // Call this function, then emit an event, then call a function. Internally after the call, we check if + // logs were emitted in the expected order with the expected topics and data. + // Second form also checks supplied address against emitting contract. + function expectEmit() external; + function expectEmit(address emitter) external; + + // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). + // Call this function, then emit an event, then call a function. Internally after the call, we check if + // logs were emitted in the expected order with the expected topics and data (as specified by the booleans). + // Second form also checks supplied address against emitting contract. + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) + external; + + // Mocks a call to an address, returning specified data. + // Calldata can either be strict or a partial match, e.g. if you only + // pass a Solidity selector to the expected calldata, then the entire Solidity + // function will be mocked. + function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; + // Mocks a call to an address with a specific msg.value, returning specified data. + // Calldata match takes precedence over msg.value in case of ambiguity. + function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; + // Reverts a call to an address with specified revert data. + function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; + // Reverts a call to an address with a specific msg.value, with specified revert data. + function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) + external; + // Clears all mocked calls + function clearMockedCalls() external; + // Expects a call to an address with the specified calldata. + // Calldata can either be a strict or a partial match + function expectCall(address callee, bytes calldata data) external; + // Expects given number of calls to an address with the specified calldata. + function expectCall(address callee, bytes calldata data, uint64 count) external; + // Expects a call to an address with the specified msg.value and calldata + function expectCall(address callee, uint256 msgValue, bytes calldata data) external; + // Expects given number of calls to an address with the specified msg.value and calldata + function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external; + // Expect a call to an address with the specified msg.value, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; + // Expects given number of calls to an address with the specified msg.value, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external; + // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; + // Expect given number of calls to an address with the specified msg.value and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) + external; + // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other + // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. + function expectSafeMemory(uint64 min, uint64 max) external; + // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. + // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges + // to the set. + function expectSafeMemoryCall(uint64 min, uint64 max) external; + // Sets block.coinbase + function coinbase(address newCoinbase) external; + // Snapshot the current state of the evm. + // Returns the id of the snapshot that was created. + // To revert a snapshot use `revertTo` + function snapshot() external returns (uint256 snapshotId); + // Revert the state of the EVM to a previous snapshot + // Takes the snapshot id to revert to. + // This deletes the snapshot and all snapshots taken after the given snapshot id. + function revertTo(uint256 snapshotId) external returns (bool success); + // Creates a new fork with the given endpoint and block and returns the identifier of the fork + function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork + function createFork(string calldata urlOrAlias) external returns (uint256 forkId); + // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction, + // and returns the identifier of the fork + function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork + function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before + // the transaction, returns the identifier of the fork + function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork + function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); + // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. + function selectFork(uint256 forkId) external; + /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. + function activeFork() external view returns (uint256 forkId); + // Updates the currently active fork to given block number + // This is similar to `roll` but for the currently active fork + function rollFork(uint256 blockNumber) external; + // Updates the currently active fork to given transaction + // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block + function rollFork(bytes32 txHash) external; + // Updates the given fork to given block number + function rollFork(uint256 forkId, uint256 blockNumber) external; + // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block + function rollFork(uint256 forkId, bytes32 txHash) external; + // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup + // Meaning, changes made to the state of this account will be kept when switching forks + function makePersistent(address account) external; + function makePersistent(address account0, address account1) external; + function makePersistent(address account0, address account1, address account2) external; + function makePersistent(address[] calldata accounts) external; + // Revokes persistent status from the address, previously added via `makePersistent` + function revokePersistent(address account) external; + function revokePersistent(address[] calldata accounts) external; + // Returns true if the account is marked as persistent + function isPersistent(address account) external view returns (bool persistent); + // In forking mode, explicitly grant the given address cheatcode access + function allowCheatcodes(address account) external; + // Fetches the given transaction from the active fork and executes it on the current state + function transact(bytes32 txHash) external; + // Fetches the given transaction from the given fork and executes it on the current state + function transact(uint256 forkId, bytes32 txHash) external; +} diff --git a/lens-protocol/modules/lib/forge-std/src/console.sol b/lens-protocol/modules/lib/forge-std/src/console.sol new file mode 100644 index 0000000..ad57e53 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/console.sol @@ -0,0 +1,1533 @@ +// 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/lens-protocol/modules/lib/forge-std/src/console2.sol b/lens-protocol/modules/lib/forge-std/src/console2.sol new file mode 100644 index 0000000..c1e2cd7 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/console2.sol @@ -0,0 +1,1558 @@ +// 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/lens-protocol/modules/lib/forge-std/src/interfaces/IERC1155.sol b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC1155.sol new file mode 100644 index 0000000..f7dd2b4 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC1155.sol @@ -0,0 +1,105 @@ +// 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/lens-protocol/modules/lib/forge-std/src/interfaces/IERC165.sol b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC165.sol new file mode 100644 index 0000000..9af4bf8 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC165.sol @@ -0,0 +1,12 @@ +// 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/lens-protocol/modules/lib/forge-std/src/interfaces/IERC20.sol b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC20.sol new file mode 100644 index 0000000..ba40806 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC20.sol @@ -0,0 +1,43 @@ +// 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/lens-protocol/modules/lib/forge-std/src/interfaces/IERC4626.sol b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC4626.sol new file mode 100644 index 0000000..bfe3a11 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC4626.sol @@ -0,0 +1,190 @@ +// 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/lens-protocol/modules/lib/forge-std/src/interfaces/IERC721.sol b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC721.sol new file mode 100644 index 0000000..0a16f45 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/interfaces/IERC721.sol @@ -0,0 +1,164 @@ +// 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/lens-protocol/modules/lib/forge-std/src/interfaces/IMulticall3.sol b/lens-protocol/modules/lib/forge-std/src/interfaces/IMulticall3.sol new file mode 100644 index 0000000..0d031b7 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/interfaces/IMulticall3.sol @@ -0,0 +1,73 @@ +// 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/lens-protocol/modules/lib/forge-std/src/safeconsole.sol b/lens-protocol/modules/lib/forge-std/src/safeconsole.sol new file mode 100644 index 0000000..5714d09 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/src/safeconsole.sol @@ -0,0 +1,13248 @@ +// 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/lens-protocol/modules/lib/forge-std/test/StdAssertions.t.sol b/lens-protocol/modules/lib/forge-std/test/StdAssertions.t.sol new file mode 100644 index 0000000..fcc346b --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/StdAssertions.t.sol @@ -0,0 +1,999 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdAssertionsTest is Test { + string constant CUSTOM_ERROR = "guh!"; + + bool constant EXPECT_PASS = false; + bool constant EXPECT_FAIL = true; + + bool constant SHOULD_REVERT = true; + bool constant SHOULD_RETURN = false; + + bool constant STRICT_REVERT_DATA = true; + bool constant NON_STRICT_REVERT_DATA = false; + + TestTest t = new TestTest(); + + /*////////////////////////////////////////////////////////////////////////// + FAIL(STRING) + //////////////////////////////////////////////////////////////////////////*/ + + function testShouldFail() external { + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._fail(CUSTOM_ERROR); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_FALSE + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertFalse_Pass() external { + t._assertFalse(false, EXPECT_PASS); + } + + function testAssertFalse_Fail() external { + vm.expectEmit(false, false, false, true); + emit log("Error: Assertion Failed"); + t._assertFalse(true, EXPECT_FAIL); + } + + function testAssertFalse_Err_Pass() external { + t._assertFalse(false, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertFalse_Err_Fail() external { + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertFalse(true, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(BOOL) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEq_Bool_Pass(bool a) external { + t._assertEq(a, a, EXPECT_PASS); + } + + function testAssertEq_Bool_Fail(bool a, bool b) external { + vm.assume(a != b); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [bool]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_BoolErr_Pass(bool a) external { + t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertEq_BoolErr_Fail(bool a, bool b) external { + vm.assume(a != b); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(BYTES) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEq_Bytes_Pass(bytes calldata a) external { + t._assertEq(a, a, EXPECT_PASS); + } + + function testAssertEq_Bytes_Fail(bytes calldata a, bytes calldata b) external { + vm.assume(keccak256(a) != keccak256(b)); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [bytes]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_BytesErr_Pass(bytes calldata a) external { + t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertEq_BytesErr_Fail(bytes calldata a, bytes calldata b) external { + vm.assume(keccak256(a) != keccak256(b)); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(ARRAY) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEq_UintArr_Pass(uint256 e0, uint256 e1, uint256 e2) public { + uint256[] memory a = new uint256[](3); + a[0] = e0; + a[1] = e1; + a[2] = e2; + uint256[] memory b = new uint256[](3); + b[0] = e0; + b[1] = e1; + b[2] = e2; + + t._assertEq(a, b, EXPECT_PASS); + } + + function testAssertEq_IntArr_Pass(int256 e0, int256 e1, int256 e2) public { + int256[] memory a = new int256[](3); + a[0] = e0; + a[1] = e1; + a[2] = e2; + int256[] memory b = new int256[](3); + b[0] = e0; + b[1] = e1; + b[2] = e2; + + t._assertEq(a, b, EXPECT_PASS); + } + + function testAssertEq_AddressArr_Pass(address e0, address e1, address e2) public { + address[] memory a = new address[](3); + a[0] = e0; + a[1] = e1; + a[2] = e2; + address[] memory b = new address[](3); + b[0] = e0; + b[1] = e1; + b[2] = e2; + + t._assertEq(a, b, EXPECT_PASS); + } + + function testAssertEq_UintArr_FailEl(uint256 e1) public { + vm.assume(e1 != 0); + uint256[] memory a = new uint256[](3); + uint256[] memory b = new uint256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_IntArr_FailEl(int256 e1) public { + vm.assume(e1 != 0); + int256[] memory a = new int256[](3); + int256[] memory b = new int256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_AddressArr_FailEl(address e1) public { + vm.assume(e1 != address(0)); + address[] memory a = new address[](3); + address[] memory b = new address[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_UintArrErr_FailEl(uint256 e1) public { + vm.assume(e1 != 0); + uint256[] memory a = new uint256[](3); + uint256[] memory b = new uint256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_IntArrErr_FailEl(int256 e1) public { + vm.assume(e1 != 0); + int256[] memory a = new int256[](3); + int256[] memory b = new int256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_AddressArrErr_FailEl(address e1) public { + vm.assume(e1 != address(0)); + address[] memory a = new address[](3); + address[] memory b = new address[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_UintArr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + uint256[] memory a = new uint256[](lenA); + uint256[] memory b = new uint256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_IntArr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + int256[] memory a = new int256[](lenA); + int256[] memory b = new int256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_AddressArr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + address[] memory a = new address[](lenA); + address[] memory b = new address[](lenB); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_UintArrErr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + uint256[] memory a = new uint256[](lenA); + uint256[] memory b = new uint256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_IntArrErr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + int256[] memory a = new int256[](lenA); + int256[] memory b = new int256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_AddressArrErr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + address[] memory a = new address[](lenA); + address[] memory b = new address[](lenB); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEqUint() public { + assertEqUint(uint8(1), uint128(1)); + assertEqUint(uint64(2), uint64(2)); + } + + function testFailAssertEqUint() public { + assertEqUint(uint64(1), uint96(2)); + assertEqUint(uint160(3), uint160(4)); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbs_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); + } + + function testAssertApproxEqAbs_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); + } + + function testAssertApproxEqAbs_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbs_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS_DECIMAL(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbsDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqAbsDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbs_Int_Pass(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); + } + + function testAssertApproxEqAbs_Int_Fail(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); + } + + function testAssertApproxEqAbs_IntErr_Pass(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbs_IntErr_Fail(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS_DECIMAL(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbsDecimal_Int_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_Int_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqAbsDecimal_IntErr_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_IntErr_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRel_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); + } + + function testAssertApproxEqRel_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); + } + + function testAssertApproxEqRel_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRel_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL_DECIMAL(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRelDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqRelDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRel_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); + } + + function testAssertApproxEqRel_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); + } + + function testAssertApproxEqRel_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRel_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL_DECIMAL(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRelDecimal_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqRelDecimal_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ_CALL + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEqCall_Return_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnData, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnData, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnData, SHOULD_RETURN)); + + t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_PASS); + } + + function testAssertEqCall_Return_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + vm.assume(keccak256(returnDataA) != keccak256(returnDataB)); + + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN)); + + vm.expectEmit(true, true, true, true); + emit log_named_string("Error", "Call return data does not match"); + t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); + } + + function testAssertEqCall_Revert_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + t._assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA, EXPECT_PASS); + } + + function testAssertEqCall_Revert_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + vm.assume(keccak256(revertDataA) != keccak256(revertDataB)); + + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + vm.expectEmit(true, true, true, true); + emit log_named_string("Error", "Call revert data does not match"); + t._assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA, EXPECT_FAIL); + } + + function testAssertEqCall_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT)); + + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Left call return data", returnDataA); + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Right call revert data", returnDataB); + t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); + + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Left call revert data", returnDataB); + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Right call return data", returnDataA); + t._assertEqCall(targetB, callDataB, targetA, callDataA, strictRevertData, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_NOT_EQ(BYTES) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertNotEq_Bytes_Pass(bytes32 a, bytes32 b) external { + vm.assume(a != b); + t._assertNotEq(a, b, EXPECT_PASS); + } + + function testAssertNotEq_Bytes_Fail(bytes32 a) external { + vm.expectEmit(false, false, false, true); + emit log("Error: a != b not satisfied [bytes32]"); + t._assertNotEq(a, a, EXPECT_FAIL); + } + + function testAssertNotEq_BytesErr_Pass(bytes32 a, bytes32 b) external { + vm.assume(a != b); + t._assertNotEq(a, b, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAsserNottEq_BytesErr_Fail(bytes32 a) external { + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertNotEq(a, a, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_NOT_EQ(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertNotEqUint() public { + assertNotEq(uint8(1), uint128(2)); + assertNotEq(uint64(3), uint64(4)); + } + + function testFailAssertNotEqUint() public { + assertNotEq(uint64(1), uint96(1)); + assertNotEq(uint160(2), uint160(2)); + } +} + +contract TestTest is Test { + modifier expectFailure(bool expectFail) { + bool preState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); + _; + bool postState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); + + if (preState == true) { + return; + } + + if (expectFail) { + require(postState == true, "expected failure not triggered"); + + // unwind the expected failure + vm.store(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x00))); + } else { + require(postState == false, "unexpected failure was triggered"); + } + } + + function _fail(string memory err) external expectFailure(true) { + fail(err); + } + + function _assertFalse(bool data, bool expectFail) external expectFailure(expectFail) { + assertFalse(data); + } + + function _assertFalse(bool data, string memory err, bool expectFail) external expectFailure(expectFail) { + assertFalse(data, err); + } + + function _assertEq(bool a, bool b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(bool a, bool b, string memory err, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b, err); + } + + function _assertEq(bytes memory a, bytes memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(bytes memory a, bytes memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertEq(uint256[] memory a, uint256[] memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(int256[] memory a, int256[] memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(address[] memory a, address[] memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(uint256[] memory a, uint256[] memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertEq(int256[] memory a, int256[] memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertEq(address[] memory a, address[] memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertNotEq(bytes32 a, bytes32 b, bool expectFail) external expectFailure(expectFail) { + assertNotEq32(a, b); + } + + function _assertNotEq(bytes32 a, bytes32 b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertNotEq32(a, b, err); + } + + function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta); + } + + function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta, err); + } + + function _assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + + function _assertApproxEqAbsDecimal( + uint256 a, + uint256 b, + uint256 maxDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); + } + + function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta); + } + + function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta, err); + } + + function _assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + + function _assertApproxEqAbsDecimal( + int256 a, + int256 b, + uint256 maxDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); + } + + function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta); + } + + function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta, err); + } + + function _assertApproxEqRelDecimal(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + + function _assertApproxEqRelDecimal( + uint256 a, + uint256 b, + uint256 maxPercentDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); + } + + function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta); + } + + function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta, err); + } + + function _assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + + function _assertApproxEqRelDecimal( + int256 a, + int256 b, + uint256 maxPercentDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); + } + + function _assertEqCall( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData, + bool expectFail + ) external expectFailure(expectFail) { + assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); + } +} + +contract TestMockCall { + bytes returnData; + bool shouldRevert; + + constructor(bytes memory returnData_, bool shouldRevert_) { + returnData = returnData_; + shouldRevert = shouldRevert_; + } + + fallback() external payable { + bytes memory returnData_ = returnData; + + if (shouldRevert) { + assembly { + revert(add(returnData_, 0x20), mload(returnData_)) + } + } else { + assembly { + return(add(returnData_, 0x20), mload(returnData_)) + } + } + } +} diff --git a/lens-protocol/modules/lib/forge-std/test/StdChains.t.sol b/lens-protocol/modules/lib/forge-std/test/StdChains.t.sol new file mode 100644 index 0000000..f0ede99 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/StdChains.t.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdChainsTest is Test { + function testChainRpcInitialization() public { + // RPCs specified in `foundry.toml` should be updated. + assertEq(getChain(1).rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); + assertEq(getChain("optimism_goerli").rpcUrl, "https://goerli.optimism.io/"); + assertEq(getChain("arbitrum_one_goerli").rpcUrl, "https://goerli-rollup.arbitrum.io/rpc/"); + + // Environment variables should be the next fallback + assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride"); + assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc"); + + // Cannot override RPCs defined in `foundry.toml` + vm.setEnv("MAINNET_RPC_URL", "myoverride2"); + assertEq(getChain("mainnet").rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); + + // Other RPCs should remain unchanged. + assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545"); + assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001"); + } + + function testRpc(string memory rpcAlias) internal { + string memory rpcUrl = getChain(rpcAlias).rpcUrl; + vm.createSelectFork(rpcUrl); + } + + // Ensure we can connect to the default RPC URL for each chain. + // function testRpcs() public { + // testRpc("mainnet"); + // testRpc("goerli"); + // testRpc("sepolia"); + // testRpc("optimism"); + // testRpc("optimism_goerli"); + // testRpc("arbitrum_one"); + // testRpc("arbitrum_one_goerli"); + // testRpc("arbitrum_nova"); + // testRpc("polygon"); + // testRpc("polygon_mumbai"); + // testRpc("avalanche"); + // testRpc("avalanche_fuji"); + // testRpc("bnb_smart_chain"); + // testRpc("bnb_smart_chain_testnet"); + // testRpc("gnosis_chain"); + // } + + function testChainNoDefault() public { + vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found."); + getChain("does_not_exist"); + } + + function testSetChainFirstFails() public { + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\"."); + setChain("anvil2", ChainData("Anvil", 31337, "URL")); + } + + function testChainBubbleUp() public { + setChain("needs_undefined_env_var", ChainData("", 123456789, "")); + vm.expectRevert( + "Failed to resolve env var `UNDEFINED_RPC_URL_PLACEHOLDER` in `${UNDEFINED_RPC_URL_PLACEHOLDER}`: environment variable not found" + ); + getChain("needs_undefined_env_var"); + } + + function testCannotSetChain_ChainIdExists() public { + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + + vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".'); + + setChain("another_custom_chain", ChainData("", 123456789, "")); + } + + function testSetChain() public { + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + Chain memory customChain = getChain("custom_chain"); + assertEq(customChain.name, "Custom Chain"); + assertEq(customChain.chainId, 123456789); + assertEq(customChain.chainAlias, "custom_chain"); + assertEq(customChain.rpcUrl, "https://custom.chain/"); + Chain memory chainById = getChain(123456789); + assertEq(chainById.name, customChain.name); + assertEq(chainById.chainId, customChain.chainId); + assertEq(chainById.chainAlias, customChain.chainAlias); + assertEq(chainById.rpcUrl, customChain.rpcUrl); + customChain.name = "Another Custom Chain"; + customChain.chainId = 987654321; + setChain("another_custom_chain", customChain); + Chain memory anotherCustomChain = getChain("another_custom_chain"); + assertEq(anotherCustomChain.name, "Another Custom Chain"); + assertEq(anotherCustomChain.chainId, 987654321); + assertEq(anotherCustomChain.chainAlias, "another_custom_chain"); + assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/"); + // Verify the first chain data was not overwritten + chainById = getChain(123456789); + assertEq(chainById.name, "Custom Chain"); + assertEq(chainById.chainId, 123456789); + } + + function testSetNoEmptyAlias() public { + vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string."); + setChain("", ChainData("", 123456789, "")); + } + + function testSetNoChainId0() public { + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0."); + setChain("alias", ChainData("", 0, "")); + } + + function testGetNoChainId0() public { + vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0."); + getChain(0); + } + + function testGetNoEmptyAlias() public { + vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string."); + getChain(""); + } + + function testChainIdNotFound() public { + vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found."); + getChain("no_such_alias"); + } + + function testChainAliasNotFound() public { + vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found."); + getChain(321); + } + + function testSetChain_ExistingOne() public { + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + assertEq(getChain(123456789).chainId, 123456789); + + setChain("custom_chain", ChainData("Modified Chain", 999999999, "https://modified.chain/")); + vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found."); + getChain(123456789); + + Chain memory modifiedChain = getChain(999999999); + assertEq(modifiedChain.name, "Modified Chain"); + assertEq(modifiedChain.chainId, 999999999); + assertEq(modifiedChain.rpcUrl, "https://modified.chain/"); + } + + function testDontUseDefaultRpcUrl() public { + // Should error if default RPCs flag is set to false. + setFallbackToDefaultRpcUrls(false); + vm.expectRevert( + "Failed to get environment variable `ANVIL_RPC_URL` as type `string`: environment variable not found" + ); + getChain(31337); + vm.expectRevert( + "Failed to get environment variable `SEPOLIA_RPC_URL` as type `string`: environment variable not found" + ); + getChain("sepolia"); + } +} diff --git a/lens-protocol/modules/lib/forge-std/test/StdCheats.t.sol b/lens-protocol/modules/lib/forge-std/test/StdCheats.t.sol new file mode 100644 index 0000000..6f4d5bb --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/StdCheats.t.sol @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/StdCheats.sol"; +import "../src/Test.sol"; +import "../src/StdJson.sol"; + +contract StdCheatsTest is Test { + Bar test; + + using stdJson for string; + + function setUp() public { + test = new Bar(); + } + + function testSkip() public { + vm.warp(100); + skip(25); + assertEq(block.timestamp, 125); + } + + function testRewind() public { + vm.warp(100); + rewind(25); + assertEq(block.timestamp, 75); + } + + function testHoax() public { + hoax(address(1337)); + test.bar{value: 100}(address(1337)); + } + + function testHoaxOrigin() public { + hoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + } + + function testHoaxDifferentAddresses() public { + hoax(address(1337), address(7331)); + test.origin{value: 100}(address(1337), address(7331)); + } + + function testStartHoax() public { + startHoax(address(1337)); + test.bar{value: 100}(address(1337)); + test.bar{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function testStartHoaxOrigin() public { + startHoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + test.origin{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function testChangePrankMsgSender() public { + vm.startPrank(address(1337)); + test.bar(address(1337)); + changePrank(address(0xdead)); + test.bar(address(0xdead)); + changePrank(address(1337)); + test.bar(address(1337)); + vm.stopPrank(); + } + + function testChangePrankMsgSenderAndTxOrigin() public { + vm.startPrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + changePrank(address(0xdead), address(0xbeef)); + test.origin(address(0xdead), address(0xbeef)); + changePrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + vm.stopPrank(); + } + + function testMakeAccountEquivalence() public { + Account memory account = makeAccount("1337"); + (address addr, uint256 key) = makeAddrAndKey("1337"); + assertEq(account.addr, addr); + assertEq(account.key, key); + } + + function testMakeAddrEquivalence() public { + (address addr,) = makeAddrAndKey("1337"); + assertEq(makeAddr("1337"), addr); + } + + function testMakeAddrSigning() public { + (address addr, uint256 key) = makeAddrAndKey("1337"); + bytes32 hash = keccak256("some_message"); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); + assertEq(ecrecover(hash, v, r, s), addr); + } + + function testDeal() public { + deal(address(this), 1 ether); + assertEq(address(this).balance, 1 ether); + } + + function testDealToken() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18); + assertEq(barToken.balanceOf(address(this)), 10000e18); + } + + function testDealTokenAdjustTotalSupply() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18, true); + assertEq(barToken.balanceOf(address(this)), 10000e18); + assertEq(barToken.totalSupply(), 20000e18); + deal(bar, address(this), 0, true); + assertEq(barToken.balanceOf(address(this)), 0); + assertEq(barToken.totalSupply(), 10000e18); + } + + function testDealERC1155Token() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, false); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + } + + function testDealERC1155TokenAdjustTotalSupply() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, true); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + assertEq(barToken.totalSupply(0), 20000e18); + dealERC1155(bar, address(this), 0, 0, true); + assertEq(barToken.balanceOf(address(this), 0), 0); + assertEq(barToken.totalSupply(0), 10000e18); + } + + function testDealERC721Token() public { + BarERC721 barToken = new BarERC721(); + address bar = address(barToken); + dealERC721(bar, address(2), 1); + assertEq(barToken.balanceOf(address(2)), 1); + assertEq(barToken.balanceOf(address(1)), 0); + dealERC721(bar, address(1), 2); + assertEq(barToken.balanceOf(address(1)), 1); + assertEq(barToken.balanceOf(bar), 1); + } + + function testDeployCode() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function testDestroyAccount() public { + // deploy something to destroy it + BarERC721 barToken = new BarERC721(); + address bar = address(barToken); + vm.setNonce(bar, 10); + deal(bar, 100); + + uint256 prevThisBalance = address(this).balance; + uint256 size; + assembly { + size := extcodesize(bar) + } + + assertGt(size, 0); + assertEq(bar.balance, 100); + assertEq(vm.getNonce(bar), 10); + + destroyAccount(bar, address(this)); + assembly { + size := extcodesize(bar) + } + assertEq(address(this).balance, prevThisBalance + 100); + assertEq(vm.getNonce(bar), 0); + assertEq(size, 0); + assertEq(bar.balance, 0); + } + + function testDeployCodeNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar"); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function testDeployCodeVal() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + function testDeployCodeValNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + // We need this so we can call "this.deployCode" rather than "deployCode" directly + function deployCodeHelper(string memory what) external { + deployCode(what); + } + + function testDeployCodeFail() public { + vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); + this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); + } + + function getCode(address who) internal view returns (bytes memory o_code) { + /// @solidity memory-safe-assembly + assembly { + // retrieve the size of the code, this needs assembly + let size := extcodesize(who) + // allocate output byte array - this could also be done without assembly + // by using o_code = new bytes(size) + o_code := mload(0x40) + // new "memory end" including padding + mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + // store length in memory + mstore(o_code, size) + // actually retrieve the code, this needs assembly + extcodecopy(who, add(o_code, 0x20), 0, size) + } + } + + function testDeriveRememberKey() public { + string memory mnemonic = "test test test test test test test test test test test junk"; + + (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); + assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); + } + + function testBytesToUint() public { + assertEq(3, bytesToUint_test(hex"03")); + assertEq(2, bytesToUint_test(hex"02")); + assertEq(255, bytesToUint_test(hex"ff")); + assertEq(29625, bytesToUint_test(hex"73b9")); + } + + function testParseJsonTxDetail() public { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + string memory json = vm.readFile(path); + bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); + RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); + Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); + assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); + assertEq( + txDetail.data, + hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" + ); + assertEq(txDetail.nonce, 3); + assertEq(txDetail.txType, 2); + assertEq(txDetail.gas, 29625); + assertEq(txDetail.value, 0); + } + + function testReadEIP1559Transaction() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 0; + Tx1559 memory transaction = readTx1559(path, index); + transaction; + } + + function testReadEIP1559Transactions() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Tx1559[] memory transactions = readTx1559s(path); + transactions; + } + + function testReadReceipt() public { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 5; + Receipt memory receipt = readReceipt(path, index); + assertEq( + receipt.logsBloom, + hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" + ); + } + + function testReadReceipts() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Receipt[] memory receipts = readReceipts(path); + receipts; + } + + function testGasMeteringModifier() public { + uint256 gas_start_normal = gasleft(); + addInLoop(); + uint256 gas_used_normal = gas_start_normal - gasleft(); + + uint256 gas_start_single = gasleft(); + addInLoopNoGas(); + uint256 gas_used_single = gas_start_single - gasleft(); + + uint256 gas_start_double = gasleft(); + addInLoopNoGasNoGas(); + uint256 gas_used_double = gas_start_double - gasleft(); + + emit log_named_uint("Normal gas", gas_used_normal); + emit log_named_uint("Single modifier gas", gas_used_single); + emit log_named_uint("Double modifier gas", gas_used_double); + assertTrue(gas_used_double + gas_used_single < gas_used_normal); + } + + function addInLoop() internal pure returns (uint256) { + uint256 b; + for (uint256 i; i < 10000; i++) { + b += i; + } + return b; + } + + function addInLoopNoGas() internal noGasMetering returns (uint256) { + return addInLoop(); + } + + function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) { + return addInLoopNoGas(); + } + + function bytesToUint_test(bytes memory b) private pure returns (uint256) { + uint256 number; + for (uint256 i = 0; i < b.length; i++) { + number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); + } + return number; + } + + function testAssumeNoPrecompiles(address addr) external { + assumeNoPrecompiles(addr, getChain("optimism_goerli").chainId); + assertTrue( + addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) + || addr > address(0x4200000000000000000000000000000000000800) + ); + } + + function testAssumePayable() external { + // all should revert since these addresses are not payable + + // VM address + vm.expectRevert(); + assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + // Console address + vm.expectRevert(); + assumePayable(0x000000000000000000636F6e736F6c652e6c6f67); + + // Create2Deployer + vm.expectRevert(); + assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); + } + + function testAssumePayable(address addr) external { + assumePayable(addr); + assertTrue( + addr != 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D && addr != 0x000000000000000000636F6e736F6c652e6c6f67 + && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C + ); + } +} + +contract StdCheatsMock is StdCheats { + // We deploy a mock version so we can properly test expected reverts. + function assumeNoBlacklisted_(address token, address addr) external { + return assumeNoBlacklisted(token, addr); + } +} + +contract StdCheatsForkTest is Test { + address internal constant SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; + address internal constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address internal constant USDC_BLACKLISTED_USER = 0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD; + address internal constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; + address internal constant USDT_BLACKLISTED_USER = 0x8f8a8F4B54a2aAC7799d7bc81368aC27b852822A; + + // We deploy a mock version so we can properly test the revert. + StdCheatsMock private stdCheats = new StdCheatsMock(); + + function setUp() public { + // All tests of the `assumeNoBlacklisted` method are fork tests using live contracts. + vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); + } + + function testCannotAssumeNoBlacklisted_EOA() external { + address eoa = vm.addr({privateKey: 1}); + vm.expectRevert("StdCheats assumeNoBlacklisted(address,address): Token address is not a contract."); + assumeNoBlacklisted(eoa, address(0)); + } + + function testAssumeNoBlacklisted_TokenWithoutBlacklist(address addr) external { + assumeNoBlacklisted(SHIB, addr); + assertTrue(true); + } + + function testAssumeNoBlacklisted_USDC() external { + vm.expectRevert(); + stdCheats.assumeNoBlacklisted_(USDC, USDC_BLACKLISTED_USER); + } + + function testAssumeNoBlacklisted_USDC(address addr) external { + assumeNoBlacklisted(USDC, addr); + assertFalse(USDCLike(USDC).isBlacklisted(addr)); + } + + function testAssumeNoBlacklisted_USDT() external { + vm.expectRevert(); + stdCheats.assumeNoBlacklisted_(USDT, USDT_BLACKLISTED_USER); + } + + function testAssumeNoBlacklisted_USDT(address addr) external { + assumeNoBlacklisted(USDT, addr); + assertFalse(USDTLike(USDT).isBlackListed(addr)); + } +} + +contract Bar { + constructor() payable { + /// `DEAL` STDCHEAT + totalSupply = 10000e18; + balanceOf[address(this)] = totalSupply; + } + + /// `HOAX` and `CHANGEPRANK` STDCHEATS + function bar(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + } + + function origin(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedSender, "!prank"); + } + + function origin(address expectedSender, address expectedOrigin) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedOrigin, "!prank"); + } + + /// `DEAL` STDCHEAT + mapping(address => uint256) public balanceOf; + uint256 public totalSupply; +} + +contract BarERC1155 { + constructor() payable { + /// `DEALERC1155` STDCHEAT + _totalSupply[0] = 10000e18; + _balances[0][address(this)] = _totalSupply[0]; + } + + function balanceOf(address account, uint256 id) public view virtual returns (uint256) { + return _balances[id][account]; + } + + function totalSupply(uint256 id) public view virtual returns (uint256) { + return _totalSupply[id]; + } + + /// `DEALERC1155` STDCHEAT + mapping(uint256 => mapping(address => uint256)) private _balances; + mapping(uint256 => uint256) private _totalSupply; +} + +contract BarERC721 { + constructor() payable { + /// `DEALERC721` STDCHEAT + _owners[1] = address(1); + _balances[address(1)] = 1; + _owners[2] = address(this); + _owners[3] = address(this); + _balances[address(this)] = 2; + } + + function balanceOf(address owner) public view virtual returns (uint256) { + return _balances[owner]; + } + + function ownerOf(uint256 tokenId) public view virtual returns (address) { + address owner = _owners[tokenId]; + return owner; + } + + mapping(uint256 => address) private _owners; + mapping(address => uint256) private _balances; +} + +interface USDCLike { + function isBlacklisted(address) external view returns (bool); +} + +interface USDTLike { + function isBlackListed(address) external view returns (bool); +} + +contract RevertingContract { + constructor() { + revert(); + } +} diff --git a/lens-protocol/modules/lib/forge-std/test/StdError.t.sol b/lens-protocol/modules/lib/forge-std/test/StdError.t.sol new file mode 100644 index 0000000..ccd3efa --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/StdError.t.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import "../src/StdError.sol"; +import "../src/Test.sol"; + +contract StdErrorsTest is Test { + ErrorsTest test; + + function setUp() public { + test = new ErrorsTest(); + } + + function testExpectAssertion() public { + vm.expectRevert(stdError.assertionError); + test.assertionError(); + } + + function testExpectArithmetic() public { + vm.expectRevert(stdError.arithmeticError); + test.arithmeticError(10); + } + + function testExpectDiv() public { + vm.expectRevert(stdError.divisionError); + test.divError(0); + } + + function testExpectMod() public { + vm.expectRevert(stdError.divisionError); + test.modError(0); + } + + function testExpectEnum() public { + vm.expectRevert(stdError.enumConversionError); + test.enumConversion(1); + } + + function testExpectEncodeStg() public { + vm.expectRevert(stdError.encodeStorageError); + test.encodeStgError(); + } + + function testExpectPop() public { + vm.expectRevert(stdError.popError); + test.pop(); + } + + function testExpectOOB() public { + vm.expectRevert(stdError.indexOOBError); + test.indexOOBError(1); + } + + function testExpectMem() public { + vm.expectRevert(stdError.memOverflowError); + test.mem(); + } + + function testExpectIntern() public { + vm.expectRevert(stdError.zeroVarError); + test.intern(); + } +} + +contract ErrorsTest { + enum T {T1} + + uint256[] public someArr; + bytes someBytes; + + function assertionError() public pure { + assert(false); + } + + function arithmeticError(uint256 a) public pure { + a -= 100; + } + + function divError(uint256 a) public pure { + 100 / a; + } + + function modError(uint256 a) public pure { + 100 % a; + } + + function enumConversion(uint256 a) public pure { + T(a); + } + + function encodeStgError() public { + /// @solidity memory-safe-assembly + assembly { + sstore(someBytes.slot, 1) + } + keccak256(someBytes); + } + + function pop() public { + someArr.pop(); + } + + function indexOOBError(uint256 a) public pure { + uint256[] memory t = new uint256[](0); + t[a]; + } + + function mem() public pure { + uint256 l = 2 ** 256 / 32; + new uint256[](l); + } + + function intern() public returns (uint256) { + function(uint256) internal returns (uint256) x; + x(2); + return 7; + } +} diff --git a/lens-protocol/modules/lib/forge-std/test/StdMath.t.sol b/lens-protocol/modules/lib/forge-std/test/StdMath.t.sol new file mode 100644 index 0000000..95037ea --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/StdMath.t.sol @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import "../src/StdMath.sol"; +import "../src/Test.sol"; + +contract StdMathTest is Test { + function testGetAbs() external { + assertEq(stdMath.abs(-50), 50); + assertEq(stdMath.abs(50), 50); + assertEq(stdMath.abs(-1337), 1337); + assertEq(stdMath.abs(0), 0); + + assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); + assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); + } + + function testGetAbs_Fuzz(int256 a) external { + uint256 manualAbs = getAbs(a); + + uint256 abs = stdMath.abs(a); + + assertEq(abs, manualAbs); + } + + function testGetDelta_Uint() external { + assertEq(stdMath.delta(uint256(0), uint256(0)), 0); + assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); + assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); + assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); + assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); + + assertEq(stdMath.delta(0, uint256(0)), 0); + assertEq(stdMath.delta(1337, uint256(0)), 1337); + assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); + assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); + assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); + + assertEq(stdMath.delta(1337, uint256(1337)), 0); + assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); + assertEq(stdMath.delta(5000, uint256(1250)), 3750); + } + + function testGetDelta_Uint_Fuzz(uint256 a, uint256 b) external { + uint256 manualDelta; + if (a > b) { + manualDelta = a - b; + } else { + manualDelta = b - a; + } + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function testGetDelta_Int() external { + assertEq(stdMath.delta(int256(0), int256(0)), 0); + assertEq(stdMath.delta(int256(0), int256(1337)), 1337); + assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); + assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); + assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); + + assertEq(stdMath.delta(0, int256(0)), 0); + assertEq(stdMath.delta(1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); + assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); + assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); + + assertEq(stdMath.delta(-0, int256(0)), 0); + assertEq(stdMath.delta(-1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(int256(0), -0), 0); + assertEq(stdMath.delta(int256(0), -1337), 1337); + assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(1337, int256(1337)), 0); + assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); + assertEq(stdMath.delta(5000, int256(1250)), 3750); + } + + function testGetDelta_Int_Fuzz(int256 a, int256 b) external { + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function testGetPercentDelta_Uint() external { + assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); + assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); + assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); + assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); + + vm.expectRevert(stdError.divisionError); + stdMath.percentDelta(uint256(1), 0); + } + + function testGetPercentDelta_Uint_Fuzz(uint192 a, uint192 b) external { + vm.assume(b != 0); + uint256 manualDelta; + if (a > b) { + manualDelta = a - b; + } else { + manualDelta = b - a; + } + + uint256 manualPercentDelta = manualDelta * 1e18 / b; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + function testGetPercentDelta_Int() external { + assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); + assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, int256(1337)), 0); + assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); + assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); + + assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, int256(2500)), 0); + assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); + + vm.expectRevert(stdError.divisionError); + stdMath.percentDelta(int256(1), 0); + } + + function testGetPercentDelta_Int_Fuzz(int192 a, int192 b) external { + vm.assume(b != 0); + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 manualPercentDelta = manualDelta * 1e18 / absB; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + /*////////////////////////////////////////////////////////////////////////// + HELPERS + //////////////////////////////////////////////////////////////////////////*/ + + function getAbs(int256 a) private pure returns (uint256) { + if (a < 0) { + return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); + } + + return uint256(a); + } +} diff --git a/lens-protocol/modules/lib/forge-std/test/StdStorage.t.sol b/lens-protocol/modules/lib/forge-std/test/StdStorage.t.sol new file mode 100644 index 0000000..d4c563a --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/StdStorage.t.sol @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/StdStorage.sol"; +import "../src/Test.sol"; + +contract StdStorageTest is Test { + using stdStorage for StdStorage; + + StorageTest internal test; + + function setUp() public { + test = new StorageTest(); + } + + function testStorageHidden() public { + assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); + } + + function testStorageObvious() public { + assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); + } + + function testStorageCheckedWriteHidden() public { + stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); + assertEq(uint256(test.hidden()), 100); + } + + function testStorageCheckedWriteObvious() public { + stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); + assertEq(test.exists(), 100); + } + + function testStorageMapStructA() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); + } + + function testStorageMapStructB() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); + } + + function testStorageDeepMap() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key( + address(this) + ).find(); + assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); + } + + function testStorageCheckedWriteDeepMap() public { + stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) + .checked_write(100); + assertEq(100, test.deep_map(address(this), address(this))); + } + + function testStorageDeepMapStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(0).find(); + assertEq( + bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0), + bytes32(slot) + ); + } + + function testStorageDeepMapStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(1).find(); + assertEq( + bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1), + bytes32(slot) + ); + } + + function testStorageCheckedWriteDeepMapStructA() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( + address(this) + ).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(100, a); + assertEq(0, b); + } + + function testStorageCheckedWriteDeepMapStructB() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( + address(this) + ).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(0, a); + assertEq(100, b); + } + + function testStorageCheckedWriteMapStructA() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 100); + assertEq(b, 0); + } + + function testStorageCheckedWriteMapStructB() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 0); + assertEq(b, 100); + } + + function testStorageStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); + assertEq(uint256(7), slot); + } + + function testStorageStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); + assertEq(uint256(7) + 1, slot); + } + + function testStorageCheckedWriteStructA() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 100); + assertEq(b, 1337); + } + + function testStorageCheckedWriteStructB() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 1337); + assertEq(b, 100); + } + + function testStorageMapAddrFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); + assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); + } + + function testStorageMapUintFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); + assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); + } + + function testStorageCheckedWriteMapUint() public { + stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); + assertEq(100, test.map_uint(100)); + } + + function testStorageCheckedWriteMapAddr() public { + stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); + assertEq(100, test.map_addr(address(this))); + } + + function testStorageCheckedWriteMapBool() public { + stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); + assertTrue(test.map_bool(address(this))); + } + + function testFailStorageCheckedWriteMapPacked() public { + // expect PackedSlot error but not external call so cant expectRevert + stdstore.target(address(test)).sig(test.read_struct_lower.selector).with_key(address(uint160(1337))) + .checked_write(100); + } + + function testStorageCheckedWriteMapPackedSuccess() public { + uint256 full = test.map_packed(address(1337)); + // keep upper 128, set lower 128 to 1337 + full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; + stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write( + full + ); + assertEq(1337, test.read_struct_lower(address(1337))); + } + + function testFailStorageConst() public { + // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); + stdstore.target(address(test)).sig("const()").find(); + } + + function testFailStorageNativePack() public { + stdstore.target(address(test)).sig(test.tA.selector).find(); + stdstore.target(address(test)).sig(test.tB.selector).find(); + + // these both would fail + stdstore.target(address(test)).sig(test.tC.selector).find(); + stdstore.target(address(test)).sig(test.tD.selector).find(); + } + + function testStorageReadBytes32() public { + bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); + assertEq(val, hex"1337"); + } + + function testStorageReadBool_False() public { + bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); + assertEq(val, false); + } + + function testStorageReadBool_True() public { + bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); + assertEq(val, true); + } + + function testStorageReadBool_Revert() public { + vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + this.readNonBoolValue(); + } + + function readNonBoolValue() public { + stdstore.target(address(test)).sig(test.tE.selector).read_bool(); + } + + function testStorageReadAddress() public { + address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); + assertEq(val, address(1337)); + } + + function testStorageReadUint() public { + uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); + assertEq(val, 1); + } + + function testStorageReadInt() public { + int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); + assertEq(val, type(int256).min); + } +} + +contract StorageTest { + uint256 public exists = 1; + mapping(address => uint256) public map_addr; + mapping(uint256 => uint256) public map_uint; + mapping(address => uint256) public map_packed; + mapping(address => UnpackedStruct) public map_struct; + mapping(address => mapping(address => uint256)) public deep_map; + mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; + UnpackedStruct public basic; + + uint248 public tA; + bool public tB; + + bool public tC = false; + uint248 public tD = 1; + + struct UnpackedStruct { + uint256 a; + uint256 b; + } + + mapping(address => bool) public map_bool; + + bytes32 public tE = hex"1337"; + address public tF = address(1337); + int256 public tG = type(int256).min; + bool public tH = true; + + constructor() { + basic = UnpackedStruct({a: 1337, b: 1337}); + + uint256 two = (1 << 128) | 1; + map_packed[msg.sender] = two; + map_packed[address(uint160(1337))] = 1 << 128; + } + + function read_struct_upper(address who) public view returns (uint256) { + return map_packed[who] >> 128; + } + + function read_struct_lower(address who) public view returns (uint256) { + return map_packed[who] & ((1 << 128) - 1); + } + + function hidden() public view returns (bytes32 t) { + bytes32 slot = keccak256("my.random.var"); + /// @solidity memory-safe-assembly + assembly { + t := sload(slot) + } + } + + function const() public pure returns (bytes32 t) { + t = bytes32(hex"1337"); + } +} diff --git a/lens-protocol/modules/lib/forge-std/test/StdStyle.t.sol b/lens-protocol/modules/lib/forge-std/test/StdStyle.t.sol new file mode 100644 index 0000000..f6fffe7 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/StdStyle.t.sol @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdStyleTest is Test { + function testStyleColor() public pure { + console2.log(StdStyle.red("StdStyle.red String Test")); + console2.log(StdStyle.red(uint256(10e18))); + console2.log(StdStyle.red(int256(-10e18))); + console2.log(StdStyle.red(true)); + console2.log(StdStyle.red(address(0))); + console2.log(StdStyle.redBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.redBytes32("StdStyle.redBytes32")); + console2.log(StdStyle.green("StdStyle.green String Test")); + console2.log(StdStyle.green(uint256(10e18))); + console2.log(StdStyle.green(int256(-10e18))); + console2.log(StdStyle.green(true)); + console2.log(StdStyle.green(address(0))); + console2.log(StdStyle.greenBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.greenBytes32("StdStyle.greenBytes32")); + console2.log(StdStyle.yellow("StdStyle.yellow String Test")); + console2.log(StdStyle.yellow(uint256(10e18))); + console2.log(StdStyle.yellow(int256(-10e18))); + console2.log(StdStyle.yellow(true)); + console2.log(StdStyle.yellow(address(0))); + console2.log(StdStyle.yellowBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.yellowBytes32("StdStyle.yellowBytes32")); + console2.log(StdStyle.blue("StdStyle.blue String Test")); + console2.log(StdStyle.blue(uint256(10e18))); + console2.log(StdStyle.blue(int256(-10e18))); + console2.log(StdStyle.blue(true)); + console2.log(StdStyle.blue(address(0))); + console2.log(StdStyle.blueBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.blueBytes32("StdStyle.blueBytes32")); + console2.log(StdStyle.magenta("StdStyle.magenta String Test")); + console2.log(StdStyle.magenta(uint256(10e18))); + console2.log(StdStyle.magenta(int256(-10e18))); + console2.log(StdStyle.magenta(true)); + console2.log(StdStyle.magenta(address(0))); + console2.log(StdStyle.magentaBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.magentaBytes32("StdStyle.magentaBytes32")); + console2.log(StdStyle.cyan("StdStyle.cyan String Test")); + console2.log(StdStyle.cyan(uint256(10e18))); + console2.log(StdStyle.cyan(int256(-10e18))); + console2.log(StdStyle.cyan(true)); + console2.log(StdStyle.cyan(address(0))); + console2.log(StdStyle.cyanBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.cyanBytes32("StdStyle.cyanBytes32")); + } + + function testStyleFontWeight() public pure { + console2.log(StdStyle.bold("StdStyle.bold String Test")); + console2.log(StdStyle.bold(uint256(10e18))); + console2.log(StdStyle.bold(int256(-10e18))); + console2.log(StdStyle.bold(address(0))); + console2.log(StdStyle.bold(true)); + console2.log(StdStyle.boldBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.boldBytes32("StdStyle.boldBytes32")); + console2.log(StdStyle.dim("StdStyle.dim String Test")); + console2.log(StdStyle.dim(uint256(10e18))); + console2.log(StdStyle.dim(int256(-10e18))); + console2.log(StdStyle.dim(address(0))); + console2.log(StdStyle.dim(true)); + console2.log(StdStyle.dimBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.dimBytes32("StdStyle.dimBytes32")); + console2.log(StdStyle.italic("StdStyle.italic String Test")); + console2.log(StdStyle.italic(uint256(10e18))); + console2.log(StdStyle.italic(int256(-10e18))); + console2.log(StdStyle.italic(address(0))); + console2.log(StdStyle.italic(true)); + console2.log(StdStyle.italicBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.italicBytes32("StdStyle.italicBytes32")); + console2.log(StdStyle.underline("StdStyle.underline String Test")); + console2.log(StdStyle.underline(uint256(10e18))); + console2.log(StdStyle.underline(int256(-10e18))); + console2.log(StdStyle.underline(address(0))); + console2.log(StdStyle.underline(true)); + console2.log(StdStyle.underlineBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.underlineBytes32("StdStyle.underlineBytes32")); + console2.log(StdStyle.inverse("StdStyle.inverse String Test")); + console2.log(StdStyle.inverse(uint256(10e18))); + console2.log(StdStyle.inverse(int256(-10e18))); + console2.log(StdStyle.inverse(address(0))); + console2.log(StdStyle.inverse(true)); + console2.log(StdStyle.inverseBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.inverseBytes32("StdStyle.inverseBytes32")); + } + + function testStyleCombined() public pure { + console2.log(StdStyle.red(StdStyle.bold("Red Bold String Test"))); + console2.log(StdStyle.green(StdStyle.dim(uint256(10e18)))); + console2.log(StdStyle.yellow(StdStyle.italic(int256(-10e18)))); + console2.log(StdStyle.blue(StdStyle.underline(address(0)))); + console2.log(StdStyle.magenta(StdStyle.inverse(true))); + } + + function testStyleCustom() public pure { + console2.log(h1("Custom Style 1")); + console2.log(h2("Custom Style 2")); + } + + function h1(string memory a) private pure returns (string memory) { + return StdStyle.cyan(StdStyle.inverse(StdStyle.bold(a))); + } + + function h2(string memory a) private pure returns (string memory) { + return StdStyle.magenta(StdStyle.bold(StdStyle.underline(a))); + } +} diff --git a/lens-protocol/modules/lib/forge-std/test/StdUtils.t.sol b/lens-protocol/modules/lib/forge-std/test/StdUtils.t.sol new file mode 100644 index 0000000..e859124 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/StdUtils.t.sol @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdUtilsMock is StdUtils { + // We deploy a mock version so we can properly test expected reverts. + function getTokenBalances_(address token, address[] memory addresses) + external + returns (uint256[] memory balances) + { + return getTokenBalances(token, addresses); + } +} + +contract StdUtilsTest is Test { + /*////////////////////////////////////////////////////////////////////////// + BOUND UINT + //////////////////////////////////////////////////////////////////////////*/ + + function testBound() public { + assertEq(bound(uint256(5), 0, 4), 0); + assertEq(bound(uint256(0), 69, 69), 69); + assertEq(bound(uint256(0), 68, 69), 68); + assertEq(bound(uint256(10), 150, 190), 174); + assertEq(bound(uint256(300), 2800, 3200), 3107); + assertEq(bound(uint256(9999), 1337, 6666), 4669); + } + + function testBound_WithinRange() public { + assertEq(bound(uint256(51), 50, 150), 51); + assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150)); + assertEq(bound(uint256(149), 50, 150), 149); + assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150)); + } + + function testBound_EdgeCoverage() public { + assertEq(bound(uint256(0), 50, 150), 50); + assertEq(bound(uint256(1), 50, 150), 51); + assertEq(bound(uint256(2), 50, 150), 52); + assertEq(bound(uint256(3), 50, 150), 53); + assertEq(bound(type(uint256).max, 50, 150), 150); + assertEq(bound(type(uint256).max - 1, 50, 150), 149); + assertEq(bound(type(uint256).max - 2, 50, 150), 148); + assertEq(bound(type(uint256).max - 3, 50, 150), 147); + } + + function testBound_DistributionIsEven(uint256 min, uint256 size) public { + size = size % 100 + 1; + min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); + uint256 max = min + size - 1; + uint256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + i, min, max); + assertEq(result, min + (i - 1) % size); + // x < min + result = bound(min - i, min, max); + assertEq(result, max - (i - 1) % size); + } + } + + function testBound(uint256 num, uint256 min, uint256 max) public { + if (min > max) (min, max) = (max, min); + + uint256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function testBoundUint256Max() public { + assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); + assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); + } + + function testCannotBoundMaxLessThanMin() public { + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + bound(uint256(5), 100, 10); + } + + function testCannotBoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BOUND INT + //////////////////////////////////////////////////////////////////////////*/ + + function testBoundInt() public { + assertEq(bound(-3, 0, 4), 2); + assertEq(bound(0, -69, -69), -69); + assertEq(bound(0, -69, -68), -68); + assertEq(bound(-10, 150, 190), 154); + assertEq(bound(-300, 2800, 3200), 2908); + assertEq(bound(9999, -1337, 6666), 1995); + } + + function testBoundInt_WithinRange() public { + assertEq(bound(51, -50, 150), 51); + assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150)); + assertEq(bound(149, -50, 150), 149); + assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150)); + } + + function testBoundInt_EdgeCoverage() public { + assertEq(bound(type(int256).min, -50, 150), -50); + assertEq(bound(type(int256).min + 1, -50, 150), -49); + assertEq(bound(type(int256).min + 2, -50, 150), -48); + assertEq(bound(type(int256).min + 3, -50, 150), -47); + assertEq(bound(type(int256).min, 10, 150), 10); + assertEq(bound(type(int256).min + 1, 10, 150), 11); + assertEq(bound(type(int256).min + 2, 10, 150), 12); + assertEq(bound(type(int256).min + 3, 10, 150), 13); + + assertEq(bound(type(int256).max, -50, 150), 150); + assertEq(bound(type(int256).max - 1, -50, 150), 149); + assertEq(bound(type(int256).max - 2, -50, 150), 148); + assertEq(bound(type(int256).max - 3, -50, 150), 147); + assertEq(bound(type(int256).max, -50, -10), -10); + assertEq(bound(type(int256).max - 1, -50, -10), -11); + assertEq(bound(type(int256).max - 2, -50, -10), -12); + assertEq(bound(type(int256).max - 3, -50, -10), -13); + } + + function testBoundInt_DistributionIsEven(int256 min, uint256 size) public { + size = size % 100 + 1; + min = bound(min, -int256(size / 2), int256(size - size / 2)); + int256 max = min + int256(size) - 1; + int256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + int256(i), min, max); + assertEq(result, min + int256((i - 1) % size)); + // x < min + result = bound(min - int256(i), min, max); + assertEq(result, max - int256((i - 1) % size)); + } + } + + function testBoundInt(int256 num, int256 min, int256 max) public { + if (min > max) (min, max) = (max, min); + + int256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function testBoundIntInt256Max() public { + assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1); + assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max); + } + + function testBoundIntInt256Min() public { + assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min); + assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1); + } + + function testCannotBoundIntMaxLessThanMin() public { + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + bound(-5, 100, 10); + } + + function testCannotBoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public { + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BOUND PRIVATE KEY + //////////////////////////////////////////////////////////////////////////*/ + + function testBoundPrivateKey() public { + assertEq(boundPrivateKey(0), 1); + assertEq(boundPrivateKey(1), 1); + assertEq(boundPrivateKey(300), 300); + assertEq(boundPrivateKey(9999), 9999); + assertEq(boundPrivateKey(SECP256K1_ORDER - 1), SECP256K1_ORDER - 1); + assertEq(boundPrivateKey(SECP256K1_ORDER), 1); + assertEq(boundPrivateKey(SECP256K1_ORDER + 1), 2); + assertEq(boundPrivateKey(UINT256_MAX), UINT256_MAX & SECP256K1_ORDER - 1); // x&y is equivalent to x-x%y + } + + /*////////////////////////////////////////////////////////////////////////// + BYTES TO UINT + //////////////////////////////////////////////////////////////////////////*/ + + function testBytesToUint() external { + bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + bytes memory two = hex"02"; + bytes memory millionEther = hex"d3c21bcecceda1000000"; + + assertEq(bytesToUint(maxUint), type(uint256).max); + assertEq(bytesToUint(two), 2); + assertEq(bytesToUint(millionEther), 1_000_000 ether); + } + + function testCannotConvertGT32Bytes() external { + bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + bytesToUint(thirty3Bytes); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function testComputeCreateAddress() external { + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + uint256 nonce = 14; + address createAddress = computeCreateAddress(deployer, nonce); + assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE2 ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function testComputeCreate2Address() external { + bytes32 salt = bytes32(uint256(31415)); + bytes32 initcodeHash = keccak256(abi.encode(0x6080)); + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + address create2Address = computeCreate2Address(salt, initcodeHash, deployer); + assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); + } + + function testComputeCreate2AddressWithDefaultDeployer() external { + bytes32 salt = 0xc290c670fde54e5ef686f9132cbc8711e76a98f0333a438a92daa442c71403c0; + bytes32 initcodeHash = hashInitCode(hex"6080", ""); + assertEq(initcodeHash, 0x1a578b7a4b0b5755db6d121b4118d4bc68fe170dca840c59bc922f14175a76b0); + address create2Address = computeCreate2Address(salt, initcodeHash); + assertEq(create2Address, 0xc0ffEe2198a06235aAbFffe5Db0CacF1717f5Ac6); + } +} + +contract StdUtilsForkTest is Test { + /*////////////////////////////////////////////////////////////////////////// + GET TOKEN BALANCES + //////////////////////////////////////////////////////////////////////////*/ + + address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; + address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170; + address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA; + address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385; + + address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17; + address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52; + + function setUp() public { + // All tests of the `getTokenBalances` method are fork tests using live contracts. + vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); + } + + function testCannotGetTokenBalances_NonTokenContract() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function, + // so the `balanceOf` call should revert. + address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + + vm.expectRevert("Multicall3: call failed"); + stdUtils.getTokenBalances_(token, addresses); + } + + function testCannotGetTokenBalances_EOA() external { + address eoa = vm.addr({privateKey: 1}); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + getTokenBalances(eoa, addresses); + } + + function testGetTokenBalances_Empty() external { + address[] memory addresses = new address[](0); + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances.length, 0); + } + + function testGetTokenBalances_USDC() external { + address[] memory addresses = new address[](2); + addresses[0] = USDC_HOLDER_0; + addresses[1] = USDC_HOLDER_1; + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances[0], 159_000_000_000_000); + assertEq(balances[1], 131_350_000_000_000); + } + + function testGetTokenBalances_SHIB() external { + address[] memory addresses = new address[](3); + addresses[0] = SHIB_HOLDER_0; + addresses[1] = SHIB_HOLDER_1; + addresses[2] = SHIB_HOLDER_2; + uint256[] memory balances = getTokenBalances(SHIB, addresses); + assertEq(balances[0], 3_323_256_285_484.42e18); + assertEq(balances[1], 1_271_702_771_149.99999928e18); + assertEq(balances[2], 606_357_106_247e18); + } +} diff --git a/lens-protocol/modules/lib/forge-std/test/compilation/CompilationScript.sol b/lens-protocol/modules/lib/forge-std/test/compilation/CompilationScript.sol new file mode 100644 index 0000000..e205cff --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/compilation/CompilationScript.sol @@ -0,0 +1,10 @@ +// 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/lens-protocol/modules/lib/forge-std/test/compilation/CompilationScriptBase.sol b/lens-protocol/modules/lib/forge-std/test/compilation/CompilationScriptBase.sol new file mode 100644 index 0000000..ce8e0e9 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/compilation/CompilationScriptBase.sol @@ -0,0 +1,10 @@ +// 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/lens-protocol/modules/lib/forge-std/test/compilation/CompilationTest.sol b/lens-protocol/modules/lib/forge-std/test/compilation/CompilationTest.sol new file mode 100644 index 0000000..9beeafe --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/compilation/CompilationTest.sol @@ -0,0 +1,10 @@ +// 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/lens-protocol/modules/lib/forge-std/test/compilation/CompilationTestBase.sol b/lens-protocol/modules/lib/forge-std/test/compilation/CompilationTestBase.sol new file mode 100644 index 0000000..e993535 --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/compilation/CompilationTestBase.sol @@ -0,0 +1,10 @@ +// 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/lens-protocol/modules/lib/forge-std/test/fixtures/broadcast.log.json b/lens-protocol/modules/lib/forge-std/test/fixtures/broadcast.log.json new file mode 100644 index 0000000..0a0200b --- /dev/null +++ b/lens-protocol/modules/lib/forge-std/test/fixtures/broadcast.log.json @@ -0,0 +1,187 @@ +{ + "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/lens-protocol/modules/package-lock.json b/lens-protocol/modules/package-lock.json new file mode 100644 index 0000000..cbd7d7e --- /dev/null +++ b/lens-protocol/modules/package-lock.json @@ -0,0 +1,42349 @@ +{ + "name": "hardhat-project", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "hardhat-project", + "dependencies": { + "@aave/lens-protocol": "^1.0.2", + "@openzeppelin/contracts": "^4.7.3", + "solmate": "^6.6.1" + }, + "devDependencies": { + "@aave/core-v3": "1.16.2", + "@ethersproject/abi": "^5.6.3", + "@ethersproject/bignumber": "^5.6.2", + "@nomiclabs/hardhat-ethers": "^2.0.6", + "@nomiclabs/hardhat-etherscan": "^3.0.3", + "@nomiclabs/hardhat-waffle": "^2.0.3", + "@openzeppelin/contracts": "^4.7.3", + "@typechain/ethers-v5": "^7.2.0", + "@typechain/hardhat": "^2.3.1", + "@types/chai": "^4.3.1", + "@types/mocha": "^9.1.1", + "@types/node": "^12.20.52", + "@typescript-eslint/eslint-plugin": "^4.33.0", + "@typescript-eslint/parser": "^4.33.0", + "chai": "^4.3.6", + "dotenv": "^10.0.0", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.5.0", + "eslint-config-standard": "^16.0.3", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-promise": "^5.2.0", + "ethereum-waffle": "^3.4.4", + "ethers": "^5.6.6", + "hardhat": "^2.9.5", + "hardhat-contract-sizer": "^2.5.1", + "hardhat-dependency-compiler": "^1.1.3", + "hardhat-gas-reporter": "^1.0.8", + "hardhat-log-remover": "^2.0.2", + "hardhat-spdx-license-identifier": "^2.0.3", + "prettier": "^2.6.2", + "prettier-plugin-solidity": "^1.0.0-beta.13", + "solhint": "^3.3.7", + "solidity-coverage": "^0.7.21", + "ts-node": "^10.7.0", + "typechain": "^5.2.0", + "typescript": "^4.6.4" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/@aave/core-v3": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@aave/core-v3/-/core-v3-1.16.2.tgz", + "integrity": "sha512-COze5EN2kFVRSkwmpV5+5m5GaRvJWC587/0e6Z5NlTSXZ38CF+SeuKtMXhFgBXk2oDgYbuKwvjuBk+vJMgThYg==", + "dev": true, + "dependencies": { + "@nomiclabs/hardhat-etherscan": "^2.1.7", + "axios-curlirize": "^1.3.7", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aave/core-v3/node_modules/@nomiclabs/hardhat-etherscan": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz", + "integrity": "sha512-0+rj0SsZotVOcTLyDOxnOc3Gulo8upo0rsw/h+gBPcmtj91YqYJNhdARHoBxOhhE8z+5IUQPx+Dii04lXT14PA==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^5.0.2", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "node-fetch": "^2.6.0", + "semver": "^6.3.0" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@aave/lens-protocol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@aave/lens-protocol/-/lens-protocol-1.0.2.tgz", + "integrity": "sha512-yP3tMD+VmIYzb3RLyKnXw04ApinMm8yKlP1MkxzaAInGZR29gYaDJHlFHbGaMHj5P91M+c8IqYYseUwxmYlnyg==", + "dependencies": { + "@openzeppelin/contracts": "4.5.0" + } + }, + "node_modules/@aave/lens-protocol/node_modules/@openzeppelin/contracts": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.5.0.tgz", + "integrity": "sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA==" + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", + "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@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-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ensdomains/ens": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", + "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", + "deprecated": "Please use @ensdomains/ens-contracts", + "dev": true, + "dependencies": { + "bluebird": "^3.5.2", + "eth-ens-namehash": "^2.0.8", + "solc": "^0.4.20", + "testrpc": "0.0.1", + "web3-utils": "^1.0.0-beta.31" + } + }, + "node_modules/@ensdomains/ens/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/@ensdomains/ens/node_modules/get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "node_modules/@ensdomains/ens/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@ensdomains/ens/node_modules/require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/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/@ensdomains/ens/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@ensdomains/ens/node_modules/solc": { + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", + "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", + "dev": true, + "dependencies": { + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" + }, + "bin": { + "solcjs": "solcjs" + } + }, + "node_modules/@ensdomains/ens/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true + }, + "node_modules/@ensdomains/ens/node_modules/yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "dev": true, + "dependencies": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "node_modules/@ensdomains/ens/node_modules/yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + }, + "node_modules/@ensdomains/resolver": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", + "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", + "deprecated": "Please use @ensdomains/ens-contracts", + "dev": true + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@ethereum-waffle/chai": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", + "integrity": "sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==", + "dev": true, + "dependencies": { + "@ethereum-waffle/provider": "^3.4.4", + "ethers": "^5.5.2" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/compiler": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz", + "integrity": "sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==", + "dev": true, + "dependencies": { + "@resolver-engine/imports": "^0.3.3", + "@resolver-engine/imports-fs": "^0.3.3", + "@typechain/ethers-v5": "^2.0.0", + "@types/mkdirp": "^0.5.2", + "@types/node-fetch": "^2.5.5", + "ethers": "^5.0.1", + "mkdirp": "^0.5.1", + "node-fetch": "^2.6.1", + "solc": "^0.6.3", + "ts-generator": "^0.1.1", + "typechain": "^3.0.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/@typechain/ethers-v5": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", + "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==", + "dev": true, + "dependencies": { + "ethers": "^5.0.2" + }, + "peerDependencies": { + "ethers": "^5.0.0", + "typechain": "^3.0.0" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/ts-essentials": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", + "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", + "dev": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/typechain": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", + "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==", + "dev": true, + "dependencies": { + "command-line-args": "^4.0.7", + "debug": "^4.1.1", + "fs-extra": "^7.0.0", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "ts-essentials": "^6.0.3", + "ts-generator": "^0.1.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + } + }, + "node_modules/@ethereum-waffle/ens": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.4.4.tgz", + "integrity": "sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==", + "dev": true, + "dependencies": { + "@ensdomains/ens": "^0.4.4", + "@ensdomains/resolver": "^0.2.4", + "ethers": "^5.5.2" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/mock-contract": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz", + "integrity": "sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.5.0", + "ethers": "^5.5.2" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/provider": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.4.tgz", + "integrity": "sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==", + "dev": true, + "dependencies": { + "@ethereum-waffle/ens": "^3.4.4", + "ethers": "^5.5.2", + "ganache-core": "^2.13.2", + "patch-package": "^6.2.2", + "postinstall-postinstall": "^2.1.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereumjs/block": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.2.tgz", + "integrity": "sha512-mOqYWwMlAZpYUEOEqt7EfMFuVL2eyLqWWIzcf4odn6QgXY8jBI2NhVuJncrMCKeMZrsJAe7/auaRRB6YcdH+Qw==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.6.3", + "@ethereumjs/tx": "^3.5.1", + "ethereumjs-util": "^7.1.4", + "merkle-patricia-tree": "^4.2.4" + } + }, + "node_modules/@ethereumjs/blockchain": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.2.tgz", + "integrity": "sha512-Jz26iJmmsQtngerW6r5BDFaew/f2mObLrRZo3rskLOx1lmtMZ8+TX/vJexmivrnWgmAsTdNWhlKUYY4thPhPig==", + "dev": true, + "dependencies": { + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/common": "^2.6.3", + "@ethereumjs/ethash": "^1.1.0", + "debug": "^4.3.3", + "ethereumjs-util": "^7.1.4", + "level-mem": "^5.0.1", + "lru-cache": "^5.1.1", + "semaphore-async-await": "^1.5.1" + } + }, + "node_modules/@ethereumjs/common": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.4.tgz", + "integrity": "sha512-RDJh/R/EAr+B7ZRg5LfJ0BIpf/1LydFgYdvZEuTraojCbVypO2sQ+QnpP5u2wJf9DASyooKqu8O4FJEWUV6NXw==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.4" + } + }, + "node_modules/@ethereumjs/ethash": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz", + "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==", + "dev": true, + "dependencies": { + "@ethereumjs/block": "^3.5.0", + "@types/levelup": "^4.3.0", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.1.1", + "miller-rabin": "^4.0.0" + } + }, + "node_modules/@ethereumjs/tx": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", + "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.6.3", + "ethereumjs-util": "^7.1.4" + } + }, + "node_modules/@ethereumjs/vm": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.9.0.tgz", + "integrity": "sha512-0IRsj4IuF8lFDWVVLc4mFOImaSX8VWF8CGm3mXHG/LLlQ/Tryy/kKXMw/bU9D+Zw03CdteW+wCGqNFS6+mPjpg==", + "dev": true, + "dependencies": { + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/blockchain": "^5.5.2", + "@ethereumjs/common": "^2.6.4", + "@ethereumjs/tx": "^3.5.1", + "async-eventemitter": "^0.2.4", + "core-js-pure": "^3.0.1", + "debug": "^4.3.3", + "ethereumjs-util": "^7.1.4", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "merkle-patricia-tree": "^4.2.4", + "rustbn.js": "~0.2.0" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.3.tgz", + "integrity": "sha512-CxKTdoZY4zDJLWXG6HzNH6znWK0M79WzzxHegDoecE3+K32pzfHOzuXg2/oGSTecZynFgpkjYXNPOqXVJlqClw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.1" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/abstract-provider": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz", + "integrity": "sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.3", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/web": "^5.6.1" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/abstract-signer": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz", + "integrity": "sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/address": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.1" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/base64": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.1.tgz", + "integrity": "sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/constants": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.1.tgz", + "integrity": "sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.2" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/hash": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.1.tgz", + "integrity": "sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.1" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/keccak256": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.1.tgz", + "integrity": "sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/networks": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.3.tgz", + "integrity": "sha512-QZxRH7cA5Ut9TbXwZFiCyuPchdWi87ZtVNHWZd0R6YFgYtes2jQ3+bsslJ0WdyDe0i6QumqtoYqvY3rrQFRZOQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/rlp": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.1.tgz", + "integrity": "sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/signing-key": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.2.tgz", + "integrity": "sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/strings": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.1.tgz", + "integrity": "sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/transactions": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.2.tgz", + "integrity": "sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/rlp": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2" + } + }, + "node_modules/@ethersproject/abi/node_modules/@ethersproject/web": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.1.tgz", + "integrity": "sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.6.1", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.1" + } + }, + "node_modules/@ethersproject/abi/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/abstract-provider": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", + "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/web": "^5.6.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.1.tgz", + "integrity": "sha512-xhSLo6y0nGJS7NxfvOSzCaWKvWb1TLT7dQ0nnpHZrDnC67xfnWm9NXflTMFPUXXMtjr33CdV0kWDEmnbrQZ74Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", + "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", + "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.0.tgz", + "integrity": "sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.2.tgz", + "integrity": "sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bignumber/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "node_modules/@ethersproject/bytes": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", + "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", + "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.1.tgz", + "integrity": "sha512-0fpBBDoPqJMsutE6sNjg6pvCJaIcl7tliMQTMRcoUWDACfjO68CpKOJBlsEhEhmzdnu/41KbrfAeg+sB3y35MQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "^5.6.0", + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", + "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.1.tgz", + "integrity": "sha512-6IuYDmbH5Bv/WH/A2cUd0FjNr4qTLAvyHAECiFZhNZp69pPvU7qIDwJ7CU7VAkwm4IVBzqdYy9mpMAGhQdwCDA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/basex": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/sha2": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0", + "@ethersproject/strings": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/wordlists": "^5.6.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz", + "integrity": "sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/hdnode": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.0", + "@ethersproject/strings": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", + "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", + "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.2.tgz", + "integrity": "sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz", + "integrity": "sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/sha2": "^5.6.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", + "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.6.6", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.6.tgz", + "integrity": "sha512-6X6agj3NeQ4tgnvBMCjHK+CjQbz+Qmn20JTxCYZ/uymrgCEOpJtY9zeRxJIDsSi0DPw8xNAxypj95JMCsapUfA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/basex": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.0", + "@ethersproject/rlp": "^5.6.0", + "@ethersproject/sha2": "^5.6.0", + "@ethersproject/strings": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/web": "^5.6.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/random": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.0.tgz", + "integrity": "sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", + "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", + "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.1.tgz", + "integrity": "sha512-XvqQ20DH0D+bS3qlrrgh+axRMth5kD1xuvqUQUTeezxUTXBOeR6hWz2/C6FBEu39FRytyybIWrYf7YLSAKr1LQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.0.tgz", + "integrity": "sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/sha2": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", + "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", + "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/rlp": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.0.tgz", + "integrity": "sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.1.tgz", + "integrity": "sha512-oXWoOslEWtwZiViIMlGVjeKDQz/tI7JF9UkyzN9jaGj8z7sXt2SyFMb0Ev6vSAqjIzrCrNrJ/+MkAhtKnGOfZw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/hdnode": "^5.6.0", + "@ethersproject/json-wallets": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/wordlists": "^5.6.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", + "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.0.tgz", + "integrity": "sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dev": true, + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/@noble/hashes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.0.0.tgz", + "integrity": "sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg==", + "dev": true + }, + "node_modules/@noble/secp256k1": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.5.5.tgz", + "integrity": "sha512-sZ1W6gQzYnu45wPrWx8D3kwI2/U29VYTx9OjbDAd7jwRItJ0cSTMPRL/C8AWZFn9kWFLQGqEXVEE86w4Z8LpIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nomiclabs/hardhat-ethers": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.6.tgz", + "integrity": "sha512-q2Cjp20IB48rEn2NPjR1qxsIQBvFVYW9rFRCFq+bC4RUrn1Ljz3g4wM8uSlgIBZYBi2JMXxmOzFqHraczxq4Ng==", + "dev": true, + "peerDependencies": { + "ethers": "^5.0.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.3.tgz", + "integrity": "sha512-OfNtUKc/ZwzivmZnnpwWREfaYncXteKHskn3yDnz+fPBZ6wfM4GR+d5RwjREzYFWE+o5iR9ruXhWw/8fejWM9g==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^5.0.2", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "semver": "^6.3.0", + "undici": "^4.14.1" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@nomiclabs/hardhat-waffle": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.3.tgz", + "integrity": "sha512-049PHSnI1CZq6+XTbrMbMv5NaL7cednTfPenx02k3cEh8wBMLa6ys++dBETJa6JjfwgA9nBhhHQ173LJv6k2Pg==", + "dev": true, + "dependencies": { + "@types/sinon-chai": "^3.2.3", + "@types/web3": "1.0.19" + }, + "peerDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.0", + "ethereum-waffle": "^3.2.0", + "ethers": "^5.0.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.3.tgz", + "integrity": "sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==", + "dev": true + }, + "node_modules/@resolver-engine/core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", + "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "is-url": "^1.2.4", + "request": "^2.85.0" + } + }, + "node_modules/@resolver-engine/core/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@resolver-engine/fs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz", + "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==", + "dev": true, + "dependencies": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0" + } + }, + "node_modules/@resolver-engine/fs/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@resolver-engine/imports": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz", + "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==", + "dev": true, + "dependencies": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0", + "hosted-git-info": "^2.6.0", + "path-browserify": "^1.0.0", + "url": "^0.11.0" + } + }, + "node_modules/@resolver-engine/imports-fs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz", + "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==", + "dev": true, + "dependencies": { + "@resolver-engine/fs": "^0.3.3", + "@resolver-engine/imports": "^0.3.3", + "debug": "^3.1.0" + } + }, + "node_modules/@resolver-engine/imports-fs/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@resolver-engine/imports/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@scure/base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.0.0.tgz", + "integrity": "sha512-gIVaYhUsy+9s58m/ETjSJVKHhKTBMmcRb9cEV5/5dwvfDlfORjKrFsDeDHWRrm6RjcPvCLZFwGJjAjLj1gg4HA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@scure/bip32": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.0.1.tgz", + "integrity": "sha512-AU88KKTpQ+YpTLoicZ/qhFhRRIo96/tlb+8YmDDHR9yiKVjSsFZiefJO4wjS2PMTkz5/oIcw84uAq/8pleQURA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.0.0", + "@noble/secp256k1": "~1.5.2", + "@scure/base": "~1.0.0" + } + }, + "node_modules/@scure/bip39": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.0.0.tgz", + "integrity": "sha512-HrtcikLbd58PWOkl02k9V6nXWQyoa7A0+Ek9VF7z17DDk9XZAFUcIdqfh0jJXLypmizc5/8P6OxoUeKliiWv4w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.0.0", + "@scure/base": "~1.0.0" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dev": true, + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dev": true, + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dev": true, + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@solidity-parser/parser": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.1.tgz", + "integrity": "sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw==", + "dev": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@truffle/error": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.0.tgz", + "integrity": "sha512-RbUfp5VreNhsa2Q4YbBjz18rOQI909pG32bghl1hulO7IpvcqTS+C3Ge5cNbiWQ1WGzy1wIeKLW0tmQtHFB7qg==", + "dev": true + }, + "node_modules/@truffle/interface-adapter": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.16.tgz", + "integrity": "sha512-4L8/TtFSe9eW4KWeXAvi3RrD0rImbLeYB4axPLOCAitUEDCTB/iJjZ1cMkC85LbO9mwz5/AjP0i37YO10rging==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.3", + "ethers": "^4.0.32", + "web3": "1.5.3" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/ethers": { + "version": "4.0.49", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", + "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "dev": true, + "dependencies": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/ethers/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true + }, + "node_modules/@truffle/provider": { + "version": "0.2.54", + "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.54.tgz", + "integrity": "sha512-BW2bb6p7dAipUCHlRDMSswFqessXkIb8tHVRVkm6KAENIor0F4UCCPlxIzrM/ShRQ1O16jZ+0cxLMwiRWTWdLg==", + "dev": true, + "dependencies": { + "@truffle/error": "^0.1.0", + "@truffle/interface-adapter": "^0.5.16", + "web3": "1.5.3" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@typechain/ethers-v5": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-7.2.0.tgz", + "integrity": "sha512-jfcmlTvaaJjng63QsT49MT6R1HFhtO/TBMWbyzPFSzMmVIqb2tL6prnKBs4ZJrSvmgIXWy+ttSjpaxCTq8D/Tw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + }, + "peerDependencies": { + "@ethersproject/abi": "^5.0.0", + "@ethersproject/bytes": "^5.0.0", + "@ethersproject/providers": "^5.0.0", + "ethers": "^5.1.3", + "typechain": "^5.0.0", + "typescript": ">=4.0.0" + } + }, + "node_modules/@typechain/hardhat": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-2.3.1.tgz", + "integrity": "sha512-BQV8OKQi0KAzLXCdsPO0pZBNQQ6ra8A2ucC26uFX/kquRBtJu1yEyWnVSmtr07b5hyRoJRpzUeINLnyqz4/MAw==", + "dev": true, + "dependencies": { + "fs-extra": "^9.1.0" + }, + "peerDependencies": { + "hardhat": "^2.0.10", + "lodash": "^4.17.15", + "typechain": "^5.1.2" + } + }, + "node_modules/@typechain/hardhat/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typechain/hardhat/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@typechain/hardhat/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@types/abstract-leveldown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", + "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==", + "dev": true + }, + "node_modules/@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", + "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "dev": true + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/level-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", + "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==", + "dev": true + }, + "node_modules/@types/levelup": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", + "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", + "dev": true, + "dependencies": { + "@types/abstract-leveldown": "*", + "@types/level-errors": "*", + "@types/node": "*" + } + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/mkdirp": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", + "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "12.20.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", + "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==", + "dev": true + }, + "node_modules/@types/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "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/prettier": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.1.tgz", + "integrity": "sha512-XFjFHmaLVifrAKaZ+EKghFHtHSUonyw8P2Qmy2/+osBnrKbH9UYtlK10zg8/kCt47MFilll/DEDKy3DHfJ0URw==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/sinon": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz", + "integrity": "sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinon-chai": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.8.tgz", + "integrity": "sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g==", + "dev": true, + "dependencies": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", + "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "dev": true + }, + "node_modules/@types/underscore": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz", + "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==", + "dev": true + }, + "node_modules/@types/web3": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@types/web3/-/web3-1.0.19.tgz", + "integrity": "sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A==", + "dev": true, + "dependencies": { + "@types/bn.js": "*", + "@types/underscore": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "dev": true + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-leveldown": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", + "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.0.tgz", + "integrity": "sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true, + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-colors": { + "version": "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": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/antlr4": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", + "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", + "dev": true + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "dependencies": { + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ast-parents": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", + "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", + "dev": true + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-eventemitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", + "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", + "dev": true, + "dependencies": { + "async": "^2.4.0" + } + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/axios-curlirize": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/axios-curlirize/-/axios-curlirize-1.3.7.tgz", + "integrity": "sha512-csSsuMyZj1dv1fL0zRPnDAHWrmlISMvK+wx9WJI/igRVDT4VMgbf2AVenaHghFLfI1nQijXUevYEguYV6u5hjA==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true + }, + "node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-aes/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/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-rsa/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", + "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, + "node_modules/bufferutil": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", + "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dev": true, + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-callsite/node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dev": true, + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/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/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/cbor": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", + "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", + "dev": true, + "dependencies": { + "bignumber.js": "^9.0.1", + "nofilter": "^1.0.4" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/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/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/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true + }, + "node_modules/command-line-args": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz", + "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==", + "dev": true, + "dependencies": { + "array-back": "^2.0.0", + "find-replace": "^1.0.3", + "typical": "^2.6.1" + }, + "bin": { + "command-line-args": "bin/cli.js" + } + }, + "node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "dev": true, + "dependencies": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "dev": true + }, + "node_modules/core-js-pure": { + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.5.tgz", + "integrity": "sha512-8xo9R00iYD7TcV7OrC98GwxiUEAabVWO3dix+uyWjnYrx9fyASLlIX+f/3p5dW5qByaP2bcZ8X/T47s55et/tA==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cosmiconfig/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cosmiconfig/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/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 + }, + "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": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "node_modules/deferred-leveldown": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "dev": true, + "dependencies": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deferred-leveldown/node_modules/abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-port": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", + "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", + "dev": true, + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", + "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding-down": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "dev": true, + "dependencies": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.61", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz", + "integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "dependencies": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.12.0" + }, + "optionalDependencies": { + "source-map": "~0.2.0" + } + }, + "node_modules/escodegen/node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/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": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "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": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-config-standard": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peerDependencies": { + "eslint": "^7.12.1", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1 || ^5.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-promise": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", + "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", + "dev": true, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/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/eslint/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/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/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "dev": true, + "dependencies": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "node_modules/eth-ens-namehash/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", + "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.0.0-beta.146", + "@solidity-parser/parser": "^0.14.0", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^4.0.40", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^7.1.1", + "req-cwd": "^2.0.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "peerDependencies": { + "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } + } + }, + "node_modules/eth-gas-reporter/node_modules/ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/eth-gas-reporter/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.0.3.tgz", + "integrity": "sha512-NQLTW0x0CosoVb/n79x/TRHtfvS3hgNUPTUSCu0vM+9k6IIhHFFrAOJReneexjZsoZxMjJHnJn4lrE8EbnSyqQ==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.0.0", + "@noble/secp256k1": "1.5.5", + "@scure/bip32": "1.0.1", + "@scure/bip39": "1.0.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethers": { + "version": "4.0.49", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", + "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "dev": true, + "dependencies": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "dev": true, + "dependencies": { + "is-buffer": "~2.0.3" + }, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/eth-gas-reporter/node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "deprecated": "\"Please update to latest v2.3 or v2.2\"", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eth-gas-reporter/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eth-gas-reporter/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eth-gas-reporter/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eth-gas-reporter/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/eth-gas-reporter/node_modules/mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "dev": true, + "dependencies": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/eth-gas-reporter/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eth-gas-reporter/node_modules/p-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/eth-gas-reporter/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/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/eth-gas-reporter/node_modules/readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eth-gas-reporter/node_modules/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/eth-gas-reporter/node_modules/scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/eth-gas-reporter/node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/eth-gas-reporter/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "dependencies": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-lib": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/eth-lib/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/eth-lib/node_modules/ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "dev": true, + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereum-waffle": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz", + "integrity": "sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==", + "dev": true, + "dependencies": { + "@ethereum-waffle/chai": "^3.4.4", + "@ethereum-waffle/compiler": "^3.4.4", + "@ethereum-waffle/mock-contract": "^3.4.4", + "@ethereum-waffle/provider": "^3.4.4", + "ethers": "^5.0.1" + }, + "bin": { + "waffle": "bin/waffle" + }, + "engines": { + "node": ">=10.0" + } + }, + "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.4", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", + "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "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.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/ethers": { + "version": "5.6.6", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.6.tgz", + "integrity": "sha512-2B2ZmSGvRcJpHnFMBk58mkXP50njFipUBCgLK8jUTFbomhVs501cLzyMU6+Vx8YnUDQxywC3qkZvd33xWS+2FA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.6.2", + "@ethersproject/abstract-provider": "5.6.0", + "@ethersproject/abstract-signer": "5.6.1", + "@ethersproject/address": "5.6.0", + "@ethersproject/base64": "5.6.0", + "@ethersproject/basex": "5.6.0", + "@ethersproject/bignumber": "5.6.1", + "@ethersproject/bytes": "5.6.1", + "@ethersproject/constants": "5.6.0", + "@ethersproject/contracts": "5.6.1", + "@ethersproject/hash": "5.6.0", + "@ethersproject/hdnode": "5.6.1", + "@ethersproject/json-wallets": "5.6.0", + "@ethersproject/keccak256": "5.6.0", + "@ethersproject/logger": "5.6.0", + "@ethersproject/networks": "5.6.2", + "@ethersproject/pbkdf2": "5.6.0", + "@ethersproject/properties": "5.6.0", + "@ethersproject/providers": "5.6.6", + "@ethersproject/random": "5.6.0", + "@ethersproject/rlp": "5.6.0", + "@ethersproject/sha2": "5.6.0", + "@ethersproject/signing-key": "5.6.1", + "@ethersproject/solidity": "5.6.0", + "@ethersproject/strings": "5.6.0", + "@ethersproject/transactions": "5.6.0", + "@ethersproject/units": "5.6.0", + "@ethersproject/wallet": "5.6.1", + "@ethersproject/web": "5.6.0", + "@ethersproject/wordlists": "5.6.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/abi": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.2.tgz", + "integrity": "sha512-40Ixjhy+YzFtnvzIqFU13FW9hd1gMoLa3cJfSDnfnL4o8EnEG1qLiV8sNJo3sHYi9UYMfFeRuZ7kv5+vhzU7gQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/ethers/node_modules/@ethersproject/bignumber": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.1.tgz", + "integrity": "sha512-UtMeZ3GaUuF9sx2u9nPZiPP3ULcAFmXyvynR7oHl/tPrM+vldZh7ocMsoa1PqKYGnQnqUZJoqxZnGN6J0qdipA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "dev": true, + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dev": true, + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/express": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/ext": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "dev": true, + "dependencies": { + "type": "^2.5.0" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", + "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==", + "dev": true + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/find-replace": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", + "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=", + "dev": true, + "dependencies": { + "array-back": "^1.0.4", + "test-value": "^2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-replace/node_modules/array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", + "dev": true, + "dependencies": { + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "dependencies": { + "micromatch": "^4.0.2" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", + "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "dev": true + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", + "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", + "bundleDependencies": [ + "keccak", + "node-addon-api", + "node-gyp-build" + ], + "deprecated": "ganache-core is now ganache; visit https://trfl.io/g7 for details", + "dev": true, + "hasShrinkwrap": true, + "dependencies": { + "abstract-leveldown": "3.0.0", + "async": "2.6.2", + "bip39": "2.5.0", + "cachedown": "1.0.0", + "clone": "2.1.2", + "debug": "3.2.6", + "encoding-down": "5.0.4", + "eth-sig-util": "3.0.0", + "ethereumjs-abi": "0.6.8", + "ethereumjs-account": "3.0.0", + "ethereumjs-block": "2.2.2", + "ethereumjs-common": "1.5.0", + "ethereumjs-tx": "2.1.2", + "ethereumjs-util": "6.2.1", + "ethereumjs-vm": "4.2.0", + "heap": "0.2.6", + "keccak": "3.0.1", + "level-sublevel": "6.6.4", + "levelup": "3.1.1", + "lodash": "4.17.20", + "lru-cache": "5.1.1", + "merkle-patricia-tree": "3.0.0", + "patch-package": "6.2.2", + "seedrandom": "3.0.1", + "source-map-support": "0.5.12", + "tmp": "0.1.0", + "web3-provider-engine": "14.2.1", + "websocket": "1.0.32" + }, + "engines": { + "node": ">=8.9.0" + }, + "optionalDependencies": { + "ethereumjs-wallet": "0.6.5", + "web3": "1.2.11" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/abi": { + "version": "5.0.0-beta.153", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/address": ">=5.0.0-beta.128", + "@ethersproject/bignumber": ">=5.0.0-beta.130", + "@ethersproject/bytes": ">=5.0.0-beta.129", + "@ethersproject/constants": ">=5.0.0-beta.128", + "@ethersproject/hash": ">=5.0.0-beta.128", + "@ethersproject/keccak256": ">=5.0.0-beta.127", + "@ethersproject/logger": ">=5.0.0-beta.129", + "@ethersproject/properties": ">=5.0.0-beta.131", + "@ethersproject/strings": ">=5.0.0-beta.130" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/abstract-provider": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/networks": "^5.0.7", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/transactions": "^5.0.9", + "@ethersproject/web": "^5.0.12" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/abstract-signer": { + "version": "5.0.10", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.0.8", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/address": { + "version": "5.0.9", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/rlp": "^5.0.7" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/base64": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/bignumber": { + "version": "5.0.13", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "bn.js": "^4.4.0" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/bytes": { + "version": "5.0.9", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/constants": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.0.13" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/hash": { + "version": "5.0.10", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.0.10", + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/keccak256": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "js-sha3": "0.5.7" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/logger": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/@ethersproject/networks": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/properties": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/rlp": { + "version": "5.0.7", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/signing-key": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "elliptic": "6.5.3" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/strings": { + "version": "5.0.8", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/transactions": { + "version": "5.0.9", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/rlp": "^5.0.7", + "@ethersproject/signing-key": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/web": { + "version": "5.0.12", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/base64": "^5.0.7", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@sindresorhus/is": { + "version": "0.14.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/@types/bn.js": { + "version": "4.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-core/node_modules/@types/node": { + "version": "14.14.20", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/@types/pbkdf2": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-core/node_modules/@types/secp256k1": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-core/node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/ganache-core/node_modules/abstract-leveldown": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/accepts": { + "version": "1.3.7", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/aes-js": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ganache-core/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/arr-diff": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/arr-flatten": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/arr-union": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/array-unique": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/asn1": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/ganache-core/node_modules/asn1.js": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ganache-core/node_modules/assert-plus": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ganache-core/node_modules/assign-symbols": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/async": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.11" + } + }, + "node_modules/ganache-core/node_modules/async-eventemitter": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^2.4.0" + } + }, + "node_modules/ganache-core/node_modules/async-limiter": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/atob": { + "version": "2.1.2", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/ganache-core/node_modules/aws-sign2": { + "version": "0.7.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/aws4": { + "version": "1.11.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-code-frame": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ganache-core/node_modules/babel-core": { + "version": "6.26.3", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": { + "version": "0.5.1", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-generator": { + "version": "6.26.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-call-delegate": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-define-map": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-function-name": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-regex": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-replace-supers": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helpers": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-messages": { + "version": "6.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-transform": "^0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-preset-env": { + "version": "1.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/babel-register": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": { + "version": "0.4.18", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "^0.5.6" + } + }, + "node_modules/ganache-core/node_modules/babel-runtime": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/ganache-core/node_modules/babel-template": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": { + "version": "9.18.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/babel-types": { + "version": "6.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "node_modules/ganache-core/node_modules/babel-types/node_modules/to-fast-properties": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babelify": { + "version": "7.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/babylon": { + "version": "6.18.0", + "dev": true, + "license": "MIT", + "bin": { + "babylon": "bin/babylon.js" + } + }, + "node_modules/ganache-core/node_modules/backoff": { + "version": "2.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/balanced-match": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/base": { + "version": "0.11.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/base-x": { + "version": "3.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-core/node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "license": "Unlicense" + }, + "node_modules/ganache-core/node_modules/bignumber.js": { + "version": "9.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/bip39": { + "version": "2.5.0", + "dev": true, + "license": "ISC", + "dependencies": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "node_modules/ganache-core/node_modules/blakejs": { + "version": "1.1.0", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/ganache-core/node_modules/bluebird": { + "version": "3.7.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/bn.js": { + "version": "4.11.9", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/body-parser": { + "version": "1.19.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/ganache-core/node_modules/brorand": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/browserify-aes": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-core/node_modules/browserify-cipher": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/browserify-des": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/browserify-rsa": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/ganache-core/node_modules/browserify-rsa/node_modules/bn.js": { + "version": "5.1.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/browserify-sign": { + "version": "4.2.1", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": { + "version": "5.1.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/browserslist": { + "version": "3.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/ganache-core/node_modules/bs58": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/ganache-core/node_modules/bs58check": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/ganache-core/node_modules/buffer-from": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/bufferutil": { + "version": "4.0.3", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/ganache-core/node_modules/bytes": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/bytewise": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "node_modules/ganache-core/node_modules/bytewise-core": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "typewise-core": "^1.2" + } + }, + "node_modules/ganache-core/node_modules/cache-base": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/cacheable-request": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ganache-core/node_modules/cachedown": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "^2.4.1", + "lru-cache": "^3.2.0" + } + }, + "node_modules/ganache-core/node_modules/cachedown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": { + "version": "3.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/call-bind": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/caniuse-lite": { + "version": "1.0.30001174", + "dev": true, + "license": "CC-BY-4.0" + }, + "node_modules/ganache-core/node_modules/caseless": { + "version": "0.12.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/ganache-core/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/checkpoint-store": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "functional-red-black-tree": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/chownr": { + "version": "1.1.4", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ganache-core/node_modules/ci-info": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/cids": { + "version": "0.7.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/ganache-core/node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/cipher-base": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-core/node_modules/class-is": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/class-utils": { + "version": "0.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/clone": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ganache-core/node_modules/clone-response": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/collection-visit": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ganache-core/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/component-emitter": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/concat-stream": { + "version": "1.6.2", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/ganache-core/node_modules/content-disposition": { + "version": "0.5.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/content-hash": { + "version": "2.5.2", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "node_modules/ganache-core/node_modules/content-type": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/convert-source-map": { + "version": "1.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/cookie": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/cookiejar": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/copy-descriptor": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/core-js": { + "version": "2.6.12", + "dev": true, + "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/core-js-pure": { + "version": "3.8.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/ganache-core/node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/cors": { + "version": "2.8.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ganache-core/node_modules/create-ecdh": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/ganache-core/node_modules/create-hash": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/ganache-core/node_modules/create-hmac": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/ganache-core/node_modules/cross-fetch": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" + } + }, + "node_modules/ganache-core/node_modules/crypto-browserify": { + "version": "3.12.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/d": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/dashdash": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ganache-core/node_modules/debug": { + "version": "3.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/ganache-core/node_modules/decode-uri-component": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ganache-core/node_modules/decompress-response": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/deep-equal": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/defer-to-connect": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/deferred-leveldown": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~5.0.0", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/define-properties": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ganache-core/node_modules/define-property": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/defined": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ganache-core/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/des.js": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/destroy": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/detect-indent": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/diffie-hellman": { + "version": "5.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/dom-walk": { + "version": "0.1.2", + "dev": true + }, + "node_modules/ganache-core/node_modules/dotignore": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.4" + }, + "bin": { + "ignored": "bin/ignored" + } + }, + "node_modules/ganache-core/node_modules/duplexer3": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/ganache-core/node_modules/ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ganache-core/node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/electron-to-chromium": { + "version": "1.3.636", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/elliptic": { + "version": "6.5.3", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/ganache-core/node_modules/encoding-down": { + "version": "5.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "^5.0.0", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/encoding-down/node_modules/abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/ganache-core/node_modules/errno": { + "version": "0.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/ganache-core/node_modules/es-abstract": { + "version": "1.18.0-next.1", + "dev": true, + "license": "MIT", + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/es-to-primitive": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/es5-ext": { + "version": "0.10.53", + "dev": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/ganache-core/node_modules/es6-iterator": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/ganache-core/node_modules/es6-symbol": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/ganache-core/node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ganache-core/node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/etag": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eth-query": "^2.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.3", + "ethjs-util": "^0.1.3", + "json-rpc-engine": "^3.6.0", + "pify": "^2.3.0", + "tape": "^4.6.3" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/eth-ens-namehash": { + "version": "2.0.8", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-infura": { + "version": "3.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-fetch": "^2.1.1", + "eth-json-rpc-middleware": "^1.5.0", + "json-rpc-engine": "^3.4.0", + "json-rpc-error": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": { + "version": "1.6.0", + "dev": true, + "license": "ISC", + "dependencies": { + "async": "^2.5.0", + "eth-query": "^2.1.2", + "eth-tx-summary": "^3.1.2", + "ethereumjs-block": "^1.6.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.2", + "ethereumjs-vm": "^2.1.0", + "fetch-ponyfill": "^4.0.0", + "json-rpc-engine": "^3.6.0", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "tape": "^4.6.3" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-lib": { + "version": "0.1.29", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-query": { + "version": "2.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "json-rpc-random-id": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "buffer": "^5.2.1", + "elliptic": "^6.4.0", + "ethereumjs-abi": "0.6.5", + "ethereumjs-util": "^5.1.1", + "tweetnacl": "^1.0.0", + "tweetnacl-util": "^0.15.0" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": { + "version": "0.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "4.5.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary": { + "version": "3.2.4", + "dev": true, + "license": "ISC", + "dependencies": { + "async": "^2.1.2", + "clone": "^2.0.0", + "concat-stream": "^1.5.1", + "end-of-stream": "^1.1.0", + "eth-query": "^2.0.2", + "ethereumjs-block": "^1.4.1", + "ethereumjs-tx": "^1.1.1", + "ethereumjs-util": "^5.0.1", + "ethereumjs-vm": "^2.6.0", + "through2": "^2.0.3" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethashjs": { + "version": "0.0.8", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.0.2", + "miller-rabin": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": { + "version": "5.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": { + "version": "7.0.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereum-bloom-filters": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": { + "version": "0.8.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ethereum-common": { + "version": "0.0.18", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-abi": { + "version": "0.6.8", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-account": { + "version": "3.0.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-util": "^6.0.0", + "rlp": "^2.2.1", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-blockchain": { + "version": "4.0.4", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.6.1", + "ethashjs": "~0.0.7", + "ethereumjs-block": "~2.2.2", + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.1.0", + "flow-stoplight": "^1.0.0", + "level-mem": "^3.0.1", + "lru-cache": "^5.1.1", + "rlp": "^2.2.2", + "semaphore": "^1.1.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-common": { + "version": "1.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm": { + "version": "4.2.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "core-js-pure": "^3.0.1", + "ethereumjs-account": "^3.0.0", + "ethereumjs-block": "^2.2.2", + "ethereumjs-blockchain": "^4.0.3", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.2", + "ethereumjs-util": "^6.2.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1", + "util.promisify": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ethereumjs-wallet": { + "version": "0.6.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "aes-js": "^3.1.1", + "bs58check": "^2.1.2", + "ethereum-cryptography": "^0.1.3", + "ethereumjs-util": "^6.0.0", + "randombytes": "^2.0.6", + "safe-buffer": "^5.1.2", + "scryptsy": "^1.2.1", + "utf8": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "node_modules/ganache-core/node_modules/ethjs-unit": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ethjs-util": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/eventemitter3": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/events": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/ganache-core/node_modules/evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/express": { + "version": "4.17.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/ganache-core/node_modules/express/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/express/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/express/node_modules/qs": { + "version": "6.7.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/express/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ext": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/ext/node_modules/type": { + "version": "2.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/extend-shallow": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extsprintf": { + "version": "1.3.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/fake-merkle-patricia-tree": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "checkpoint-store": "^1.1.0" + } + }, + "node_modules/ganache-core/node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/fetch-ponyfill": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "~1.7.1" + } + }, + "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/finalhandler": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root": { + "version": "1.2.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "fs-extra": "^4.0.3", + "micromatch": "^3.1.4" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces": { + "version": "2.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fs-extra": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/micromatch": { + "version": "3.1.10", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/to-regex-range": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/flow-stoplight": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/for-each": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/ganache-core/node_modules/for-in": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/forever-agent": { + "version": "0.6.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/form-data": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/ganache-core/node_modules/forwarded": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/fragment-cache": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/fs-extra": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/ganache-core/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/functional-red-black-tree": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/get-intrinsic": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ganache-core/node_modules/get-value": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/getpass": { + "version": "0.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/glob": { + "version": "7.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/global": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/ganache-core/node_modules/got": { + "version": "9.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ganache-core/node_modules/got/node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/graceful-fs": { + "version": "4.2.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/har-schema": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/har-validator": { + "version": "5.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/has": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ganache-core/node_modules/has-ansi": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/has-symbol-support-x": { + "version": "1.4.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/has-symbols": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/has-value": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/hash-base": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/hash.js": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/heap": { + "version": "0.2.6", + "dev": true + }, + "node_modules/ganache-core/node_modules/hmac-drbg": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/home-or-tmp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/http-cache-semantics": { + "version": "4.1.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true + }, + "node_modules/ganache-core/node_modules/http-errors": { + "version": "1.7.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ganache-core/node_modules/http-https": { + "version": "1.0.0", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ganache-core/node_modules/http-signature": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/ganache-core/node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/idna-uts46-hx": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "punycode": "2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ganache-core/node_modules/idna-uts46-hx/node_modules/punycode": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ganache-core/node_modules/immediate": { + "version": "3.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/ganache-core/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/invariant": { + "version": "2.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/ipaddr.js": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ganache-core/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-arguments": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-callable": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-ci": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/ganache-core/node_modules/is-data-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-date-object": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-descriptor": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-extendable": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-finite": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ganache-core/node_modules/is-fn": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-function": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/is-hex-prefixed": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/is-negative-zero": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-object": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-plain-obj": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-regex": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-retry-allowed": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-symbol": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/is-windows": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/isobject": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/isstream": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/isurl": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ganache-core/node_modules/js-sha3": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/jsbn": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/json-buffer": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/json-rpc-engine": { + "version": "3.8.0", + "dev": true, + "license": "ISC", + "dependencies": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/json-rpc-error": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/ganache-core/node_modules/json-rpc-random-id": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/json-schema": { + "version": "0.2.3", + "dev": true + }, + "node_modules/ganache-core/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/json-stable-stringify": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonify": "~0.0.0" + } + }, + "node_modules/ganache-core/node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/jsonfile": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/ganache-core/node_modules/jsonify": { + "version": "0.0.0", + "dev": true, + "license": "Public Domain" + }, + "node_modules/ganache-core/node_modules/jsprim": { + "version": "1.4.1", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/ganache-core/node_modules/keccak": { + "version": "3.0.1", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-core/node_modules/keyv": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/ganache-core/node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/klaw-sync": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/ganache-core/node_modules/level-codec": { + "version": "9.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-errors": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-iterator-stream": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.5", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/level-mem": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "level-packager": "~4.0.0", + "memdown": "~3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/memdown": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~5.0.0", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/level-packager": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "encoding-down": "~5.0.0", + "levelup": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-post": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ltgt": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/level-sublevel": { + "version": "6.6.4", + "dev": true, + "license": "MIT", + "dependencies": { + "bytewise": "~1.1.0", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "level-iterator-stream": "^2.0.3", + "ltgt": "~2.1.1", + "pull-defer": "^0.2.2", + "pull-level": "^2.0.3", + "pull-stream": "^3.6.8", + "typewiselite": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/level-ws": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.8", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/levelup": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~4.0.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~3.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/levelup/node_modules/level-iterator-stream": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/lodash": { + "version": "4.17.20", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/looper": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/loose-envify": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/ganache-core/node_modules/lowercase-keys": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ganache-core/node_modules/ltgt": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/map-cache": { + "version": "0.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/map-visit": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/md5.js": { + "version": "1.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/media-typer": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/merge-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/merkle-patricia-tree": { + "version": "3.0.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.6.1", + "ethereumjs-util": "^5.2.0", + "level-mem": "^3.0.1", + "level-ws": "^1.0.0", + "readable-stream": "^3.0.6", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/miller-rabin": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/ganache-core/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/mime-db": { + "version": "1.45.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/mime-types": { + "version": "2.1.28", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.45.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/mimic-response": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/min-document": { + "version": "2.19.0", + "dev": true, + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/minimist": { + "version": "1.2.5", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/minizlib": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/ganache-core/node_modules/minizlib/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/ganache-core/node_modules/mixin-deep": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ganache-core/node_modules/mkdirp-promise": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "mkdirp": "*" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/mock-fs": { + "version": "4.13.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/multibase": { + "version": "0.6.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/ganache-core/node_modules/multicodec": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "varint": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/multihashes": { + "version": "0.4.21", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/ganache-core/node_modules/nano-json-stream-parser": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/nanomatch": { + "version": "1.2.13", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/negotiator": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/next-tick": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/nice-try": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/node-addon-api": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/node-fetch": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/ganache-core/node_modules/node-gyp-build": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/ganache-core/node_modules/normalize-url": { + "version": "4.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ganache-core/node_modules/number-to-bn": { + "version": "1.7.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/oauth-sign": { + "version": "0.9.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-inspect": { + "version": "1.9.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object-is": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ganache-core/node_modules/object-visit": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object.assign": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object.getownpropertydescriptors": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object.pick": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/oboe": { + "version": "2.1.4", + "dev": true, + "license": "BSD", + "optional": true, + "dependencies": { + "http-https": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/on-finished": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/ganache-core/node_modules/os-homedir": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/os-tmpdir": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/p-cancelable": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/p-timeout": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/p-timeout/node_modules/p-finally": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/parse-asn1": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/parse-headers": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/pascalcase": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package": { + "version": "6.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^1.2.1", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "npm": ">5" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/cross-spawn": { + "version": "6.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/tmp": { + "version": "0.0.33", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/which": { + "version": "1.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/ganache-core/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/path-parse": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/path-to-regexp": { + "version": "0.1.7", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/pbkdf2": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/ganache-core/node_modules/performance-now": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/posix-character-classes": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/precond": { + "version": "0.2.3", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/prepend-http": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/private": { + "version": "0.1.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/process": { + "version": "0.11.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/ganache-core/node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/promise-to-callback": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-fn": "^1.0.0", + "set-immediate-shim": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/proxy-addr": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ganache-core/node_modules/prr": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pseudomap": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/psl": { + "version": "1.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/public-encrypt": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/pull-cat": { + "version": "1.1.11", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pull-defer": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pull-level": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "level-post": "^1.0.7", + "pull-cat": "^1.1.9", + "pull-live": "^1.0.1", + "pull-pushable": "^2.0.0", + "pull-stream": "^3.4.0", + "pull-window": "^2.1.4", + "stream-to-pull-stream": "^1.7.1" + } + }, + "node_modules/ganache-core/node_modules/pull-live": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "pull-cat": "^1.1.9", + "pull-stream": "^3.4.0" + } + }, + "node_modules/ganache-core/node_modules/pull-pushable": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pull-stream": { + "version": "3.6.14", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/pull-window": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "looper": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/ganache-core/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/qs": { + "version": "6.5.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/query-string": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/ganache-core/node_modules/randomfill": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/ganache-core/node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/raw-body": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/readable-stream": { + "version": "2.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/ganache-core/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/regenerate": { + "version": "1.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/regenerator-runtime": { + "version": "0.11.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/regenerator-transform": { + "version": "0.10.1", + "dev": true, + "license": "BSD", + "dependencies": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "node_modules/ganache-core/node_modules/regex-not": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/regexp.prototype.flags": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/regexp.prototype.flags/node_modules/es-abstract": { + "version": "1.17.7", + "dev": true, + "license": "MIT", + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/regexpu-core": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "node_modules/ganache-core/node_modules/regjsgen": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/regjsparser": { + "version": "0.1.5", + "dev": true, + "license": "BSD", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/ganache-core/node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/ganache-core/node_modules/repeat-element": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/repeat-string": { + "version": "1.6.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ganache-core/node_modules/repeating": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/request": { + "version": "2.88.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/resolve-url": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/responselike": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/resumer": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "~2.3.4" + } + }, + "node_modules/ganache-core/node_modules/ret": { + "version": "0.1.15", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/ganache-core/node_modules/rimraf": { + "version": "2.6.3", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ganache-core/node_modules/ripemd160": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/ganache-core/node_modules/rlp": { + "version": "2.2.6", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.1" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/ganache-core/node_modules/rustbn.js": { + "version": "0.2.0", + "dev": true, + "license": "(MIT OR Apache-2.0)" + }, + "node_modules/ganache-core/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/safe-event-emitter": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "events": "^3.0.0" + } + }, + "node_modules/ganache-core/node_modules/safe-regex": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/ganache-core/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/scrypt-js": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/scryptsy": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pbkdf2": "^3.0.3" + } + }, + "node_modules/ganache-core/node_modules/secp256k1": { + "version": "4.0.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-core/node_modules/seedrandom": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/semaphore": { + "version": "1.1.0", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ganache-core/node_modules/send": { + "version": "0.17.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ganache-core/node_modules/send/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/send/node_modules/ms": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/serve-static": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ganache-core/node_modules/servify": { + "version": "0.1.12", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/set-immediate-shim": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/set-value": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/setimmediate": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/setprototypeof": { + "version": "1.1.1", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ganache-core/node_modules/sha.js": { + "version": "2.4.11", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/ganache-core/node_modules/simple-concat": { + "version": "1.0.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/simple-get": { + "version": "2.8.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon": { + "version": "0.8.2", + "dev": true, + "license": "MIT", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-node": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-util": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/source-map": { + "version": "0.5.7", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-resolve": { + "version": "0.5.3", + "dev": true, + "license": "MIT", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-support": { + "version": "0.5.12", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-url": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/split-string": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/sshpk": { + "version": "1.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/sshpk/node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "license": "Unlicense" + }, + "node_modules/ganache-core/node_modules/static-extend": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/stream-to-pull-stream": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "looper": "^3.0.0", + "pull-stream": "^3.2.3" + } + }, + "node_modules/ganache-core/node_modules/stream-to-pull-stream/node_modules/looper": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/strict-uri-encode": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/ganache-core/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/string.prototype.trim": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/string.prototype.trimend": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/string.prototype.trimstart": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/strip-hex-prefix": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js": { + "version": "0.1.40", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/fs-extra": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/get-stream": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/got": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/p-cancelable": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/prepend-http": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/url-parse-lax": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/tape": { + "version": "4.13.3", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-equal": "~1.1.1", + "defined": "~1.0.0", + "dotignore": "~0.1.2", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.6", + "has": "~1.0.3", + "inherits": "~2.0.4", + "is-regex": "~1.0.5", + "minimist": "~1.2.5", + "object-inspect": "~1.7.0", + "resolve": "~1.17.0", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.2.1", + "through": "~2.3.8" + }, + "bin": { + "tape": "bin/tape" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/glob": { + "version": "7.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/is-regex": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/object-inspect": { + "version": "1.7.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/resolve": { + "version": "1.17.0", + "dev": true, + "license": "MIT", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/tar": { + "version": "4.4.13", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/ganache-core/node_modules/tar/node_modules/fs-minipass": { + "version": "1.2.7", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/ganache-core/node_modules/tar/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/ganache-core/node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/through2": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/ganache-core/node_modules/timed-out": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/tmp": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/to-object-path": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/to-object-path/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/to-readable-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/to-regex": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/toidentifier": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/tough-cookie": { + "version": "2.5.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ganache-core/node_modules/trim-right": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/tunnel-agent": { + "version": "0.6.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/tweetnacl": { + "version": "1.0.3", + "dev": true, + "license": "Unlicense" + }, + "node_modules/ganache-core/node_modules/tweetnacl-util": { + "version": "0.15.1", + "dev": true, + "license": "Unlicense" + }, + "node_modules/ganache-core/node_modules/type": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/type-is": { + "version": "1.6.18", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/typedarray": { + "version": "0.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/typewise": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "typewise-core": "^1.2.0" + } + }, + "node_modules/ganache-core/node_modules/typewise-core": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/typewiselite": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/ultron": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/underscore": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/union-value": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/ganache-core/node_modules/unorm": { + "version": "1.6.0", + "dev": true, + "license": "MIT or GPL-2.0", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ganache-core/node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/unset-value": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/ganache-core/node_modules/urix": { + "version": "0.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/url-parse-lax": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/url-set-query": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/url-to-options": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ganache-core/node_modules/use": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/utf-8-validate": { + "version": "5.0.4", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/ganache-core/node_modules/utf8": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/util.promisify": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "for-each": "^0.3.3", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ganache-core/node_modules/uuid": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/ganache-core/node_modules/varint": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/verror": { + "version": "1.10.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/ganache-core/node_modules/web3": { + "version": "1.2.11", + "dev": true, + "hasInstallScript": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "web3-bzz": "1.2.11", + "web3-core": "1.2.11", + "web3-eth": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-shh": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-bzz": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40", + "underscore": "1.9.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.19.12", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/web3-core": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-requestmanager": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-helpers": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "underscore": "1.9.1", + "web3-eth-iban": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-method": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@ethersproject/transactions": "^5.0.0-beta.135", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-promievent": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-requestmanager": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-providers-http": "1.2.11", + "web3-providers-ipc": "1.2.11", + "web3-providers-ws": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-subscriptions": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core/node_modules/@types/node": { + "version": "12.19.12", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/web3-eth": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-accounts": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-eth-ens": "1.2.11", + "web3-eth-iban": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-abi": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@ethersproject/abi": "5.0.0-beta.153", + "underscore": "1.9.1", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-accounts": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-common": "^1.3.2", + "ethereumjs-tx": "^2.1.1", + "scrypt-js": "^3.0.1", + "underscore": "1.9.1", + "uuid": "3.3.2", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-contract": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-ens": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-iban": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-personal": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.19.12", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/web3-net": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine": { + "version": "14.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^2.5.0", + "backoff": "^2.5.0", + "clone": "^2.0.0", + "cross-fetch": "^2.1.0", + "eth-block-tracker": "^3.0.0", + "eth-json-rpc-infura": "^3.1.0", + "eth-sig-util": "3.0.0", + "ethereumjs-block": "^1.2.2", + "ethereumjs-tx": "^1.2.0", + "ethereumjs-util": "^5.1.5", + "ethereumjs-vm": "^2.3.4", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "readable-stream": "^2.2.9", + "request": "^2.85.0", + "semaphore": "^1.0.3", + "ws": "^5.1.1", + "xhr": "^2.2.0", + "xtend": "^4.0.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/eth-sig-util": { + "version": "1.4.2", + "dev": true, + "license": "ISC", + "dependencies": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "ethereumjs-util": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-codec": { + "version": "7.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-errors": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/levelup": { + "version": "1.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ltgt": { + "version": "2.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/object-keys": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/semver": { + "version": "5.4.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ws": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-providers-http": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "web3-core-helpers": "1.2.11", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-providers-ipc": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "oboe": "2.1.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-providers-ws": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "websocket": "^1.0.31" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-shh": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-net": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-utils": { + "version": "1.2.11", + "dev": true, + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.9.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-utils/node_modules/eth-lib": { + "version": "0.2.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/ganache-core/node_modules/websocket": { + "version": "1.0.32", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ganache-core/node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/whatwg-fetch": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ganache-core/node_modules/ws": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/ganache-core/node_modules/ws/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ganache-core/node_modules/xhr": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/xhr-request": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "node_modules/ganache-core/node_modules/xhr-request-promise": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "xhr-request": "^1.1.0" + } + }, + "node_modules/ganache-core/node_modules/xhr2-cookies": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "cookiejar": "^2.1.1" + } + }, + "node_modules/ganache-core/node_modules/xtend": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/yaeti": { + "version": "0.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/ganache-core/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/ghost-testrpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", + "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "bin": { + "testrpc-sc": "index.js" + } + }, + "node_modules/ghost-testrpc/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ghost-testrpc/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/ghost-testrpc/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ghost-testrpc/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/glob": { + "version": "7.2.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/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "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/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hardhat": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.5.tgz", + "integrity": "sha512-UIhjLQmccFOH87ODfFnVatI5vpwycsJ+D5+gmgOQNxUWp4c0ZenkeCE4yDEQ0tQm/zc/vz/mpskULz4aSFsPAg==", + "dev": true, + "dependencies": { + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/blockchain": "^5.5.2", + "@ethereumjs/common": "^2.6.4", + "@ethereumjs/tx": "^3.5.1", + "@ethereumjs/vm": "^5.9.0", + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@sentry/node": "^5.18.1", + "@solidity-parser/parser": "^0.14.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "abort-controller": "^3.0.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^0.1.2", + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^7.1.4", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "^7.1.3", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "lodash": "^4.17.11", + "merkle-patricia-tree": "^4.2.4", + "mnemonist": "^0.38.0", + "mocha": "^9.2.0", + "p-map": "^4.0.0", + "qs": "^6.7.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "slash": "^3.0.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "true-case-path": "^2.2.1", + "tsort": "0.0.1", + "undici": "^4.14.1", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/cli.js" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || ^16.0.0" + }, + "peerDependencies": { + "chai": "^4.2.0" + } + }, + "node_modules/hardhat-contract-sizer": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.5.1.tgz", + "integrity": "sha512-28yRb73e30aBVaZOOHTlHZFIdIasA/iFunIehrUviIJTubvdQjtSiQUo2wexHFtt71mQeMPP8qjw2sdbgatDnQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "cli-table3": "^0.6.0" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-contract-sizer/node_modules/cli-table3": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/hardhat-contract-sizer/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/hardhat-contract-sizer/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-contract-sizer/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-dependency-compiler": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.1.3.tgz", + "integrity": "sha512-bCDqsOxGST6WkbMvj4lPchYWidNSSBm5CFnkyAex1T11cGmr9otZTGl81W6f9pmrtBXbKCvr3OSuNJ6Q394sAw==", + "dev": true, + "engines": { + "node": ">=14.14.0" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", + "integrity": "sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g==", + "dev": true, + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.24", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat-log-remover": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hardhat-log-remover/-/hardhat-log-remover-2.0.2.tgz", + "integrity": "sha512-TvEWOisQmZUZ7Mlb7s4XYS/MxgZzjFJSjDI8v3uTcrD6aaXy1QtomW6D6WNsISEWtwwRlSntOGpHQwFjrz2MCw==", + "dev": true, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-spdx-license-identifier": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hardhat-spdx-license-identifier/-/hardhat-spdx-license-identifier-2.0.3.tgz", + "integrity": "sha512-G4u4I1md0tWaitX6Os7Nq9sYZ/CFdR+ibm7clCksGJ4yrtdHEZxgLjWpJ0WiALF9SoFKt03PwCe9lczDQ/5ADA==", + "dev": true, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/hardhat/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/hardhat/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/hardhat/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/hardhat/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hardhat/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/hardhat/node_modules/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": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/hardhat/node_modules/solc/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/hardhat/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "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-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", + "dev": true + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "dev": true, + "dependencies": { + "punycode": "2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "dev": true + }, + "node_modules/immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "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": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/inquirer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/inquirer/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dev": true, + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "dev": true + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "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-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", + "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonschema": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/level-codec": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "dev": true, + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-concat-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "dev": true, + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-iterator-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-mem": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", + "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", + "dev": true, + "dependencies": { + "level-packager": "^5.0.3", + "memdown": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-packager": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "dev": true, + "dependencies": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-supports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "dev": true, + "dependencies": { + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-ws": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", + "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.0", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "dev": true, + "dependencies": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, + "node_modules/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.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "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/loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true + }, + "node_modules/mcl-wasm": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", + "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", + "dev": true, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memdown": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", + "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", + "dev": true, + "dependencies": { + "abstract-leveldown": "~6.2.1", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/memdown/node_modules/abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/memdown/node_modules/immediate": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", + "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", + "dev": true + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/merkle-patricia-tree": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz", + "integrity": "sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w==", + "dev": true, + "dependencies": { + "@types/levelup": "^4.3.0", + "ethereumjs-util": "^7.1.4", + "level-mem": "^5.0.1", + "level-ws": "^2.0.0", + "readable-stream": "^3.6.0", + "semaphore-async-await": "^1.5.1" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dev": true, + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "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": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", + "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", + "dev": true, + "dependencies": { + "mkdirp": "*" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dev": true, + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/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/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/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/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/mock-fs": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", + "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "varint": "^5.0.0" + } + }, + "node_modules/multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "node_modules/nano-json-stream-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", + "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node_modules/node-environment-flags/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "dev": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nofilter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", + "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "dev": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "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.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", + "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", + "dev": true + }, + "node_modules/oboe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", + "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", + "dev": true, + "dependencies": { + "http-https": "^1.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "dev": true + }, + "node_modules/parse-headers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", + "dev": true + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/patch-package": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", + "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", + "dev": true, + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/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/patch-package/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/patch-package/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/patch-package/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/patch-package/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/patch-package/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/patch-package/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/patch-package/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/patch-package/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/patch-package/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/patch-package/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/patch-package/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/patch-package/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postinstall-postinstall": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", + "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==", + "dev": true, + "hasInstallScript": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", + "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/prettier-plugin-solidity": { + "version": "1.0.0-beta.19", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz", + "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==", + "dev": true, + "dependencies": { + "@solidity-parser/parser": "^0.14.0", + "emoji-regex": "^10.0.0", + "escape-string-regexp": "^4.0.0", + "semver": "^7.3.5", + "solidity-comments-extractor": "^0.0.7", + "string-width": "^4.2.3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "prettier": "^2.3.0" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/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/prettier-plugin-solidity/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/prettier-plugin-solidity/node_modules/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/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "dev": true, + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "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": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", + "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "dev": true, + "dependencies": { + "minimatch": "3.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=", + "dev": true, + "dependencies": { + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", + "dev": true + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sc-istanbul": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", + "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", + "dev": true, + "dependencies": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/sc-istanbul/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true + }, + "node_modules/sc-istanbul/node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "node_modules/sc-istanbul/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sc-istanbul/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semaphore-async-await": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", + "integrity": "sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo=", + "dev": true, + "engines": { + "node": ">=4.1" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/servify": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", + "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "dev": true, + "dependencies": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "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": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=", + "dev": true, + "dependencies": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "dev": true, + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/solc": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", + "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", + "dev": true, + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solc/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solhint": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.7.tgz", + "integrity": "sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ==", + "dev": true, + "dependencies": { + "@solidity-parser/parser": "^0.14.1", + "ajv": "^6.6.1", + "antlr4": "4.7.1", + "ast-parents": "0.0.1", + "chalk": "^2.4.2", + "commander": "2.18.0", + "cosmiconfig": "^5.0.7", + "eslint": "^5.6.0", + "fast-diff": "^1.1.2", + "glob": "^7.1.3", + "ignore": "^4.0.6", + "js-yaml": "^3.12.0", + "lodash": "^4.17.11", + "semver": "^6.3.0" + }, + "bin": { + "solhint": "solhint.js" + }, + "optionalDependencies": { + "prettier": "^1.14.3" + } + }, + "node_modules/solhint/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/solhint/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/solhint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/solhint/node_modules/commander": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", + "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", + "dev": true + }, + "node_modules/solhint/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/solhint/node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solhint/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/solhint/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/solhint/node_modules/eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^6.14.0 || ^8.10.0 || >=9.10.0" + } + }, + "node_modules/solhint/node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/solhint/node_modules/eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/eslint/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solhint/node_modules/espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "dependencies": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/solhint/node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "dependencies": { + "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "node_modules/solhint/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/solhint/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/solhint/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/solhint/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/solhint/node_modules/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true, + "optional": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true, + "engines": { + "node": ">=6.5.0" + } + }, + "node_modules/solhint/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/solhint/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solhint/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solhint/node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/node_modules/string-width/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/node_modules/string-width/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solhint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/solhint/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/solhint/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/solidity-comments-extractor": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", + "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", + "dev": true + }, + "node_modules/solidity-coverage": { + "version": "0.7.21", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.21.tgz", + "integrity": "sha512-O8nuzJ9yXiKUx3NdzVvHrUW0DxoNVcGzq/I7NzewNO9EZE3wYAQ4l8BwcnV64r4aC/HB6Vnw/q2sF0BQHv/3fg==", + "dev": true, + "dependencies": { + "@solidity-parser/parser": "^0.14.0", + "@truffle/provider": "^0.2.24", + "chalk": "^2.4.2", + "death": "^1.1.0", + "detect-port": "^1.3.0", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.15", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.0" + }, + "bin": { + "solidity-coverage": "plugins/bin.js" + } + }, + "node_modules/solidity-coverage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/solidity-coverage/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/solidity-coverage/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/solidity-coverage/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/solidity-coverage/node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/solidity-coverage/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/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/solidity-coverage/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/solidity-coverage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/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/solmate": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/solmate/-/solmate-6.6.1.tgz", + "integrity": "sha512-WHvRXQvGtgR6R9nmkDTz/d+oULMqf/D33rlzQyadTX2SbuTmaW7ToEjGjGtWUVCQwZsZ/JP3vbOEVv7fB50btg==" + }, + "node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sshpk/node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "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/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "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": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "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": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "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": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/swarm-js": { + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", + "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + } + }, + "node_modules/swarm-js/node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/swarm-js/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js/node_modules/got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "dev": true, + "dependencies": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swarm-js/node_modules/p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js/node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swarm-js/node_modules/url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/table": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/table/node_modules/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/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/test-value": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", + "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", + "dev": true, + "dependencies": { + "array-back": "^1.0.3", + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/test-value/node_modules/array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", + "dev": true, + "dependencies": { + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/testrpc": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", + "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", + "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/tmp-promise/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "node_modules/true-case-path": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", + "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==", + "dev": true + }, + "node_modules/ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "dev": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/ts-generator": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz", + "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==", + "dev": true, + "dependencies": { + "@types/mkdirp": "^0.5.2", + "@types/prettier": "^2.1.1", + "@types/resolve": "^0.0.8", + "chalk": "^2.4.1", + "glob": "^7.1.2", + "mkdirp": "^0.5.1", + "prettier": "^2.1.2", + "resolve": "^1.8.1", + "ts-essentials": "^1.0.0" + }, + "bin": { + "ts-generator": "dist/cli/run.js" + } + }, + "node_modules/ts-generator/node_modules/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/ts-generator/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/ts-generator/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/ts-generator/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/ts-generator/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ts-generator/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-generator/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/ts-generator/node_modules/ts-essentials": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", + "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", + "dev": true + }, + "node_modules/ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.7.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.0", + "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/acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/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": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typechain": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-5.2.0.tgz", + "integrity": "sha512-0INirvQ+P+MwJOeMct+WLkUE4zov06QxC96D+i3uGFEHoiSkZN70MKDQsaj8zkL86wQwByJReI2e7fOUwECFuw==", + "dev": true, + "dependencies": { + "@types/prettier": "^2.1.1", + "command-line-args": "^4.0.7", + "debug": "^4.1.1", + "fs-extra": "^7.0.0", + "glob": "^7.1.6", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.1.2", + "ts-essentials": "^7.0.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.1.0" + } + }, + "node_modules/typechain/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + }, + "node_modules/uglify-js": { + "version": "3.15.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", + "integrity": "sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz", + "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==", + "dev": true, + "engines": { + "node": ">=12.18" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "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/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url-set-query": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", + "dev": true + }, + "node_modules/url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "node_modules/utf-8-validate": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", + "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true + }, + "node_modules/util": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/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 + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/web3": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", + "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-bzz": "1.5.3", + "web3-core": "1.5.3", + "web3-eth": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-shh": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-bzz": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", + "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", + "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-requestmanager": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-helpers": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", + "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-helpers/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-core-helpers/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", + "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.4.0", + "@ethersproject/transactions": "^5.0.0-beta.135", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-core-method/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-promievent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", + "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-requestmanager": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", + "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", + "dev": true, + "dependencies": { + "util": "^0.12.0", + "web3-core-helpers": "1.5.3", + "web3-providers-http": "1.5.3", + "web3-providers-ipc": "1.5.3", + "web3-providers-ws": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-subscriptions": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", + "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/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/web3-core/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-core/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", + "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", + "dev": true, + "dependencies": { + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-accounts": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-eth-ens": "1.5.3", + "web3-eth-iban": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", + "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/web3-eth-abi/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-abi/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", + "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.3.0", + "@ethereumjs/tx": "^3.2.1", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", + "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@types/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/web3-eth-contract/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", + "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", + "dev": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", + "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-iban/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", + "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", + "dev": true, + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-personal/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-net": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", + "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", + "dev": true, + "dependencies": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-net/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-net/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-http": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", + "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", + "dev": true, + "dependencies": { + "web3-core-helpers": "1.5.3", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ipc": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", + "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", + "dev": true, + "dependencies": { + "oboe": "2.1.5", + "web3-core-helpers": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ws": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", + "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3", + "websocket": "^1.0.32" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-shh": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", + "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-net": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "node_modules/websocket": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", + "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "dev": true, + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "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": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "node_modules/which-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", + "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true, + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "dev": true, + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "dev": true, + "dependencies": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "node_modules/xhr-request-promise": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", + "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", + "dev": true, + "dependencies": { + "xhr-request": "^1.1.0" + } + }, + "node_modules/xhr2-cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", + "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "dev": true, + "dependencies": { + "cookiejar": "^2.1.1" + } + }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "dev": true, + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "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/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@aave/core-v3": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@aave/core-v3/-/core-v3-1.16.2.tgz", + "integrity": "sha512-COze5EN2kFVRSkwmpV5+5m5GaRvJWC587/0e6Z5NlTSXZ38CF+SeuKtMXhFgBXk2oDgYbuKwvjuBk+vJMgThYg==", + "dev": true, + "requires": { + "@nomiclabs/hardhat-etherscan": "^2.1.7", + "axios-curlirize": "^1.3.7", + "tmp-promise": "^3.0.2" + }, + "dependencies": { + "@nomiclabs/hardhat-etherscan": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz", + "integrity": "sha512-0+rj0SsZotVOcTLyDOxnOc3Gulo8upo0rsw/h+gBPcmtj91YqYJNhdARHoBxOhhE8z+5IUQPx+Dii04lXT14PA==", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^5.0.2", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "node-fetch": "^2.6.0", + "semver": "^6.3.0" + } + } + } + }, + "@aave/lens-protocol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@aave/lens-protocol/-/lens-protocol-1.0.2.tgz", + "integrity": "sha512-yP3tMD+VmIYzb3RLyKnXw04ApinMm8yKlP1MkxzaAInGZR29gYaDJHlFHbGaMHj5P91M+c8IqYYseUwxmYlnyg==", + "requires": { + "@openzeppelin/contracts": "4.5.0" + }, + "dependencies": { + "@openzeppelin/contracts": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.5.0.tgz", + "integrity": "sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA==" + } + } + }, + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", + "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@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 + }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@ensdomains/ens": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", + "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", + "dev": true, + "requires": { + "bluebird": "^3.5.2", + "eth-ens-namehash": "^2.0.8", + "solc": "^0.4.20", + "testrpc": "0.0.1", + "web3-utils": "^1.0.0-beta.31" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "solc": { + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", + "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", + "dev": true, + "requires": { + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true + }, + "yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "dev": true, + "requires": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + } + } + }, + "@ensdomains/resolver": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", + "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } + } + }, + "@ethereum-waffle/chai": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", + "integrity": "sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==", + "dev": true, + "requires": { + "@ethereum-waffle/provider": "^3.4.4", + "ethers": "^5.5.2" + } + }, + "@ethereum-waffle/compiler": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz", + "integrity": "sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==", + "dev": true, + "requires": { + "@resolver-engine/imports": "^0.3.3", + "@resolver-engine/imports-fs": "^0.3.3", + "@typechain/ethers-v5": "^2.0.0", + "@types/mkdirp": "^0.5.2", + "@types/node-fetch": "^2.5.5", + "ethers": "^5.0.1", + "mkdirp": "^0.5.1", + "node-fetch": "^2.6.1", + "solc": "^0.6.3", + "ts-generator": "^0.1.1", + "typechain": "^3.0.0" + }, + "dependencies": { + "@typechain/ethers-v5": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", + "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==", + "dev": true, + "requires": { + "ethers": "^5.0.2" + } + }, + "ts-essentials": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", + "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", + "dev": true, + "requires": {} + }, + "typechain": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", + "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==", + "dev": true, + "requires": { + "command-line-args": "^4.0.7", + "debug": "^4.1.1", + "fs-extra": "^7.0.0", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "ts-essentials": "^6.0.3", + "ts-generator": "^0.1.1" + } + } + } + }, + "@ethereum-waffle/ens": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.4.4.tgz", + "integrity": "sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==", + "dev": true, + "requires": { + "@ensdomains/ens": "^0.4.4", + "@ensdomains/resolver": "^0.2.4", + "ethers": "^5.5.2" + } + }, + "@ethereum-waffle/mock-contract": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz", + "integrity": "sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.5.0", + "ethers": "^5.5.2" + } + }, + "@ethereum-waffle/provider": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.4.tgz", + "integrity": "sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==", + "dev": true, + "requires": { + "@ethereum-waffle/ens": "^3.4.4", + "ethers": "^5.5.2", + "ganache-core": "^2.13.2", + "patch-package": "^6.2.2", + "postinstall-postinstall": "^2.1.0" + } + }, + "@ethereumjs/block": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.2.tgz", + "integrity": "sha512-mOqYWwMlAZpYUEOEqt7EfMFuVL2eyLqWWIzcf4odn6QgXY8jBI2NhVuJncrMCKeMZrsJAe7/auaRRB6YcdH+Qw==", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.6.3", + "@ethereumjs/tx": "^3.5.1", + "ethereumjs-util": "^7.1.4", + "merkle-patricia-tree": "^4.2.4" + } + }, + "@ethereumjs/blockchain": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.2.tgz", + "integrity": "sha512-Jz26iJmmsQtngerW6r5BDFaew/f2mObLrRZo3rskLOx1lmtMZ8+TX/vJexmivrnWgmAsTdNWhlKUYY4thPhPig==", + "dev": true, + "requires": { + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/common": "^2.6.3", + "@ethereumjs/ethash": "^1.1.0", + "debug": "^4.3.3", + "ethereumjs-util": "^7.1.4", + "level-mem": "^5.0.1", + "lru-cache": "^5.1.1", + "semaphore-async-await": "^1.5.1" + } + }, + "@ethereumjs/common": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.4.tgz", + "integrity": "sha512-RDJh/R/EAr+B7ZRg5LfJ0BIpf/1LydFgYdvZEuTraojCbVypO2sQ+QnpP5u2wJf9DASyooKqu8O4FJEWUV6NXw==", + "dev": true, + "requires": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.4" + } + }, + "@ethereumjs/ethash": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz", + "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==", + "dev": true, + "requires": { + "@ethereumjs/block": "^3.5.0", + "@types/levelup": "^4.3.0", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.1.1", + "miller-rabin": "^4.0.0" + } + }, + "@ethereumjs/tx": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", + "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.6.3", + "ethereumjs-util": "^7.1.4" + } + }, + "@ethereumjs/vm": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.9.0.tgz", + "integrity": "sha512-0IRsj4IuF8lFDWVVLc4mFOImaSX8VWF8CGm3mXHG/LLlQ/Tryy/kKXMw/bU9D+Zw03CdteW+wCGqNFS6+mPjpg==", + "dev": true, + "requires": { + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/blockchain": "^5.5.2", + "@ethereumjs/common": "^2.6.4", + "@ethereumjs/tx": "^3.5.1", + "async-eventemitter": "^0.2.4", + "core-js-pure": "^3.0.1", + "debug": "^4.3.3", + "ethereumjs-util": "^7.1.4", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "merkle-patricia-tree": "^4.2.4", + "rustbn.js": "~0.2.0" + } + }, + "@ethersproject/abi": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.3.tgz", + "integrity": "sha512-CxKTdoZY4zDJLWXG6HzNH6znWK0M79WzzxHegDoecE3+K32pzfHOzuXg2/oGSTecZynFgpkjYXNPOqXVJlqClw==", + "dev": true, + "requires": { + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.1" + }, + "dependencies": { + "@ethersproject/abstract-provider": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz", + "integrity": "sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.3", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/web": "^5.6.1" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz", + "integrity": "sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ==", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "@ethersproject/address": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.1" + } + }, + "@ethersproject/base64": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.1.tgz", + "integrity": "sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.1" + } + }, + "@ethersproject/constants": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.1.tgz", + "integrity": "sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.6.2" + } + }, + "@ethersproject/hash": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.1.tgz", + "integrity": "sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA==", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.1" + } + }, + "@ethersproject/keccak256": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.1.tgz", + "integrity": "sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.1", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/networks": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.3.tgz", + "integrity": "sha512-QZxRH7cA5Ut9TbXwZFiCyuPchdWi87ZtVNHWZd0R6YFgYtes2jQ3+bsslJ0WdyDe0i6QumqtoYqvY3rrQFRZOQ==", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/rlp": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.1.tgz", + "integrity": "sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.2.tgz", + "integrity": "sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.1.tgz", + "integrity": "sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/transactions": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.2.tgz", + "integrity": "sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q==", + "dev": true, + "requires": { + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/rlp": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2" + } + }, + "@ethersproject/web": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.1.tgz", + "integrity": "sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA==", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.6.1", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.1" + } + }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + } + } + }, + "@ethersproject/abstract-provider": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", + "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/web": "^5.6.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.1.tgz", + "integrity": "sha512-xhSLo6y0nGJS7NxfvOSzCaWKvWb1TLT7dQ0nnpHZrDnC67xfnWm9NXflTMFPUXXMtjr33CdV0kWDEmnbrQZ74Q==", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "@ethersproject/address": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", + "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.0" + } + }, + "@ethersproject/base64": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", + "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0" + } + }, + "@ethersproject/basex": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.0.tgz", + "integrity": "sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.2.tgz", + "integrity": "sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "bn.js": "^5.2.1" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + } + } + }, + "@ethersproject/bytes": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", + "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/constants": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", + "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.6.0" + } + }, + "@ethersproject/contracts": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.1.tgz", + "integrity": "sha512-0fpBBDoPqJMsutE6sNjg6pvCJaIcl7tliMQTMRcoUWDACfjO68CpKOJBlsEhEhmzdnu/41KbrfAeg+sB3y35MQ==", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.6.0", + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.0" + } + }, + "@ethersproject/hash": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", + "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "@ethersproject/hdnode": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.1.tgz", + "integrity": "sha512-6IuYDmbH5Bv/WH/A2cUd0FjNr4qTLAvyHAECiFZhNZp69pPvU7qIDwJ7CU7VAkwm4IVBzqdYy9mpMAGhQdwCDA==", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/basex": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/sha2": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0", + "@ethersproject/strings": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/wordlists": "^5.6.0" + } + }, + "@ethersproject/json-wallets": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz", + "integrity": "sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ==", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/hdnode": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.0", + "@ethersproject/strings": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "@ethersproject/keccak256": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", + "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", + "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.2.tgz", + "integrity": "sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA==", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/pbkdf2": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz", + "integrity": "sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/sha2": "^5.6.0" + } + }, + "@ethersproject/properties": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", + "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/providers": { + "version": "5.6.6", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.6.tgz", + "integrity": "sha512-6X6agj3NeQ4tgnvBMCjHK+CjQbz+Qmn20JTxCYZ/uymrgCEOpJtY9zeRxJIDsSi0DPw8xNAxypj95JMCsapUfA==", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/basex": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.0", + "@ethersproject/rlp": "^5.6.0", + "@ethersproject/sha2": "^5.6.0", + "@ethersproject/strings": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/web": "^5.6.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "@ethersproject/random": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.0.tgz", + "integrity": "sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/rlp": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", + "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/sha2": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", + "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "hash.js": "1.1.7" + } + }, + "@ethersproject/signing-key": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.1.tgz", + "integrity": "sha512-XvqQ20DH0D+bS3qlrrgh+axRMth5kD1xuvqUQUTeezxUTXBOeR6hWz2/C6FBEu39FRytyybIWrYf7YLSAKr1LQ==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/solidity": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.0.tgz", + "integrity": "sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/sha2": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "@ethersproject/strings": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", + "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/transactions": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", + "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", + "dev": true, + "requires": { + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/rlp": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0" + } + }, + "@ethersproject/units": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.0.tgz", + "integrity": "sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/wallet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.1.tgz", + "integrity": "sha512-oXWoOslEWtwZiViIMlGVjeKDQz/tI7JF9UkyzN9jaGj8z7sXt2SyFMb0Ev6vSAqjIzrCrNrJ/+MkAhtKnGOfZw==", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/hdnode": "^5.6.0", + "@ethersproject/json-wallets": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/wordlists": "^5.6.0" + } + }, + "@ethersproject/web": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", + "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "@ethersproject/wordlists": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.0.tgz", + "integrity": "sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dev": true, + "requires": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, + "@noble/hashes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.0.0.tgz", + "integrity": "sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg==", + "dev": true + }, + "@noble/secp256k1": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.5.5.tgz", + "integrity": "sha512-sZ1W6gQzYnu45wPrWx8D3kwI2/U29VYTx9OjbDAd7jwRItJ0cSTMPRL/C8AWZFn9kWFLQGqEXVEE86w4Z8LpIQ==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@nomiclabs/hardhat-ethers": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.6.tgz", + "integrity": "sha512-q2Cjp20IB48rEn2NPjR1qxsIQBvFVYW9rFRCFq+bC4RUrn1Ljz3g4wM8uSlgIBZYBi2JMXxmOzFqHraczxq4Ng==", + "dev": true, + "requires": {} + }, + "@nomiclabs/hardhat-etherscan": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.3.tgz", + "integrity": "sha512-OfNtUKc/ZwzivmZnnpwWREfaYncXteKHskn3yDnz+fPBZ6wfM4GR+d5RwjREzYFWE+o5iR9ruXhWw/8fejWM9g==", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^5.0.2", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "semver": "^6.3.0", + "undici": "^4.14.1" + } + }, + "@nomiclabs/hardhat-waffle": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.3.tgz", + "integrity": "sha512-049PHSnI1CZq6+XTbrMbMv5NaL7cednTfPenx02k3cEh8wBMLa6ys++dBETJa6JjfwgA9nBhhHQ173LJv6k2Pg==", + "dev": true, + "requires": { + "@types/sinon-chai": "^3.2.3", + "@types/web3": "1.0.19" + } + }, + "@openzeppelin/contracts": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.3.tgz", + "integrity": "sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==", + "dev": true + }, + "@resolver-engine/core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", + "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "is-url": "^1.2.4", + "request": "^2.85.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@resolver-engine/fs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz", + "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==", + "dev": true, + "requires": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@resolver-engine/imports": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz", + "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==", + "dev": true, + "requires": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0", + "hosted-git-info": "^2.6.0", + "path-browserify": "^1.0.0", + "url": "^0.11.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@resolver-engine/imports-fs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz", + "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==", + "dev": true, + "requires": { + "@resolver-engine/fs": "^0.3.3", + "@resolver-engine/imports": "^0.3.3", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@scure/base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.0.0.tgz", + "integrity": "sha512-gIVaYhUsy+9s58m/ETjSJVKHhKTBMmcRb9cEV5/5dwvfDlfORjKrFsDeDHWRrm6RjcPvCLZFwGJjAjLj1gg4HA==", + "dev": true + }, + "@scure/bip32": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.0.1.tgz", + "integrity": "sha512-AU88KKTpQ+YpTLoicZ/qhFhRRIo96/tlb+8YmDDHR9yiKVjSsFZiefJO4wjS2PMTkz5/oIcw84uAq/8pleQURA==", + "dev": true, + "requires": { + "@noble/hashes": "~1.0.0", + "@noble/secp256k1": "~1.5.2", + "@scure/base": "~1.0.0" + } + }, + "@scure/bip39": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.0.0.tgz", + "integrity": "sha512-HrtcikLbd58PWOkl02k9V6nXWQyoa7A0+Ek9VF7z17DDk9XZAFUcIdqfh0jJXLypmizc5/8P6OxoUeKliiWv4w==", + "dev": true, + "requires": { + "@noble/hashes": "~1.0.0", + "@scure/base": "~1.0.0" + } + }, + "@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dev": true, + "requires": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dev": true, + "requires": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + } + }, + "@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "dev": true + }, + "@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dev": true, + "requires": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@solidity-parser/parser": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.1.tgz", + "integrity": "sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw==", + "dev": true, + "requires": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@truffle/error": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.0.tgz", + "integrity": "sha512-RbUfp5VreNhsa2Q4YbBjz18rOQI909pG32bghl1hulO7IpvcqTS+C3Ge5cNbiWQ1WGzy1wIeKLW0tmQtHFB7qg==", + "dev": true + }, + "@truffle/interface-adapter": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.16.tgz", + "integrity": "sha512-4L8/TtFSe9eW4KWeXAvi3RrD0rImbLeYB4axPLOCAitUEDCTB/iJjZ1cMkC85LbO9mwz5/AjP0i37YO10rging==", + "dev": true, + "requires": { + "bn.js": "^5.1.3", + "ethers": "^4.0.32", + "web3": "1.5.3" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "ethers": { + "version": "4.0.49", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", + "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "dev": true, + "requires": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "dev": true + }, + "setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "dev": true + }, + "uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "dev": true + } + } + }, + "@truffle/provider": { + "version": "0.2.54", + "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.54.tgz", + "integrity": "sha512-BW2bb6p7dAipUCHlRDMSswFqessXkIb8tHVRVkm6KAENIor0F4UCCPlxIzrM/ShRQ1O16jZ+0cxLMwiRWTWdLg==", + "dev": true, + "requires": { + "@truffle/error": "^0.1.0", + "@truffle/interface-adapter": "^0.5.16", + "web3": "1.5.3" + } + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "@typechain/ethers-v5": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-7.2.0.tgz", + "integrity": "sha512-jfcmlTvaaJjng63QsT49MT6R1HFhtO/TBMWbyzPFSzMmVIqb2tL6prnKBs4ZJrSvmgIXWy+ttSjpaxCTq8D/Tw==", + "dev": true, + "requires": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + } + }, + "@typechain/hardhat": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-2.3.1.tgz", + "integrity": "sha512-BQV8OKQi0KAzLXCdsPO0pZBNQQ6ra8A2ucC26uFX/kquRBtJu1yEyWnVSmtr07b5hyRoJRpzUeINLnyqz4/MAw==", + "dev": true, + "requires": { + "fs-extra": "^9.1.0" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "@types/abstract-leveldown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", + "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==", + "dev": true + }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/chai": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", + "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "dev": true + }, + "@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "@types/level-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", + "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==", + "dev": true + }, + "@types/levelup": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", + "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", + "dev": true, + "requires": { + "@types/abstract-leveldown": "*", + "@types/level-errors": "*", + "@types/node": "*" + } + }, + "@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "@types/mkdirp": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", + "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, + "@types/node": { + "version": "12.20.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", + "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==", + "dev": true + }, + "@types/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==", + "dev": true, + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/prettier": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.1.tgz", + "integrity": "sha512-XFjFHmaLVifrAKaZ+EKghFHtHSUonyw8P2Qmy2/+osBnrKbH9UYtlK10zg8/kCt47MFilll/DEDKy3DHfJ0URw==", + "dev": true + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/sinon": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz", + "integrity": "sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g==", + "dev": true, + "requires": { + "@types/sinonjs__fake-timers": "*" + } + }, + "@types/sinon-chai": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.8.tgz", + "integrity": "sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sinonjs__fake-timers": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", + "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "dev": true + }, + "@types/underscore": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz", + "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==", + "dev": true + }, + "@types/web3": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@types/web3/-/web3-1.0.19.tgz", + "integrity": "sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A==", + "dev": true, + "requires": { + "@types/bn.js": "*", + "@types/underscore": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + } + }, + "@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "dev": true + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "abstract-leveldown": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", + "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "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 + }, + "address": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.0.tgz", + "integrity": "sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig==", + "dev": true + }, + "adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true + }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "optional": true + }, + "ansi-colors": { + "version": "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 + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "antlr4": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", + "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", + "dev": true + }, + "antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "requires": { + "typical": "^2.6.1" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true + }, + "array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "ast-parents": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", + "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-eventemitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", + "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", + "dev": true, + "requires": { + "async": "^2.4.0" + } + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "axios-curlirize": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/axios-curlirize/-/axios-curlirize-1.3.7.tgz", + "integrity": "sha512-csSsuMyZj1dv1fL0zRPnDAHWrmlISMvK+wx9WJI/igRVDT4VMgbf2AVenaHghFLfI1nQijXUevYEguYV6u5hjA==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + } + } + }, + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true + }, + "bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "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 + } + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + } + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + } + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", + "dev": true + }, + "buffer-xor": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", + "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "bufferutil": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", + "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", + "dev": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dev": true, + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true + } + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "cbor": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", + "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", + "dev": true, + "requires": { + "bignumber.js": "^9.0.1", + "nofilter": "^1.0.4" + } + }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "dependencies": { + "multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "dev": true, + "requires": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + } + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true + }, + "command-line-args": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz", + "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "find-replace": "^1.0.3", + "typical": "^2.6.1" + } + }, + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "dev": true, + "requires": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "dev": true + }, + "core-js-pure": { + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.5.tgz", + "integrity": "sha512-8xo9R00iYD7TcV7OrC98GwxiUEAabVWO3dix+uyWjnYrx9fyASLlIX+f/3p5dW5qByaP2bcZ8X/T47s55et/tA==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "dependencies": { + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "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 + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "deferred-leveldown": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "dev": true, + "requires": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "dependencies": { + "abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + } + } + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, + "detect-port": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", + "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", + "dev": true, + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "emoji-regex": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", + "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "encoding-down": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "dev": true, + "requires": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.61", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz", + "integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==", + "dev": true, + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true, + "requires": {} + }, + "eslint-config-standard": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", + "dev": true, + "requires": {} + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + } + } + }, + "eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-promise": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", + "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "dev": true, + "requires": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + }, + "dependencies": { + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + } + } + }, + "eth-gas-reporter": { + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", + "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.0.0-beta.146", + "@solidity-parser/parser": "^0.14.0", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^4.0.40", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^7.1.1", + "req-cwd": "^2.0.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "ethereum-cryptography": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.0.3.tgz", + "integrity": "sha512-NQLTW0x0CosoVb/n79x/TRHtfvS3hgNUPTUSCu0vM+9k6IIhHFFrAOJReneexjZsoZxMjJHnJn4lrE8EbnSyqQ==", + "dev": true, + "requires": { + "@noble/hashes": "1.0.0", + "@noble/secp256k1": "1.5.5", + "@scure/bip32": "1.0.1", + "@scure/bip39": "1.0.0" + } + }, + "ethers": { + "version": "4.0.49", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", + "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "dev": true, + "requires": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "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 + }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, + "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 + }, + "scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "dev": true + }, + "setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + } + } + }, + "eth-lib": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "dev": true, + "requires": { + "js-sha3": "^0.8.0" + } + }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "ethereum-waffle": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz", + "integrity": "sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==", + "dev": true, + "requires": { + "@ethereum-waffle/chai": "^3.4.4", + "@ethereum-waffle/compiler": "^3.4.4", + "@ethereum-waffle/mock-contract": "^3.4.4", + "@ethereum-waffle/provider": "^3.4.4", + "ethers": "^5.0.1" + } + }, + "ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "dev": true, + "requires": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, + "ethereumjs-util": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", + "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "dev": true, + "requires": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + } + } + }, + "ethers": { + "version": "5.6.6", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.6.tgz", + "integrity": "sha512-2B2ZmSGvRcJpHnFMBk58mkXP50njFipUBCgLK8jUTFbomhVs501cLzyMU6+Vx8YnUDQxywC3qkZvd33xWS+2FA==", + "dev": true, + "requires": { + "@ethersproject/abi": "5.6.2", + "@ethersproject/abstract-provider": "5.6.0", + "@ethersproject/abstract-signer": "5.6.1", + "@ethersproject/address": "5.6.0", + "@ethersproject/base64": "5.6.0", + "@ethersproject/basex": "5.6.0", + "@ethersproject/bignumber": "5.6.1", + "@ethersproject/bytes": "5.6.1", + "@ethersproject/constants": "5.6.0", + "@ethersproject/contracts": "5.6.1", + "@ethersproject/hash": "5.6.0", + "@ethersproject/hdnode": "5.6.1", + "@ethersproject/json-wallets": "5.6.0", + "@ethersproject/keccak256": "5.6.0", + "@ethersproject/logger": "5.6.0", + "@ethersproject/networks": "5.6.2", + "@ethersproject/pbkdf2": "5.6.0", + "@ethersproject/properties": "5.6.0", + "@ethersproject/providers": "5.6.6", + "@ethersproject/random": "5.6.0", + "@ethersproject/rlp": "5.6.0", + "@ethersproject/sha2": "5.6.0", + "@ethersproject/signing-key": "5.6.1", + "@ethersproject/solidity": "5.6.0", + "@ethersproject/strings": "5.6.0", + "@ethersproject/transactions": "5.6.0", + "@ethersproject/units": "5.6.0", + "@ethersproject/wallet": "5.6.1", + "@ethersproject/web": "5.6.0", + "@ethersproject/wordlists": "5.6.0" + }, + "dependencies": { + "@ethersproject/abi": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.2.tgz", + "integrity": "sha512-40Ixjhy+YzFtnvzIqFU13FW9hd1gMoLa3cJfSDnfnL4o8EnEG1qLiV8sNJo3sHYi9UYMfFeRuZ7kv5+vhzU7gQ==", + "dev": true, + "requires": { + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.1.tgz", + "integrity": "sha512-UtMeZ3GaUuF9sx2u9nPZiPP3ULcAFmXyvynR7oHl/tPrM+vldZh7ocMsoa1PqKYGnQnqUZJoqxZnGN6J0qdipA==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "bn.js": "^4.11.9" + } + } + } + }, + "ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true + } + } + }, + "ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + } + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "express": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ext": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "dev": true, + "requires": { + "type": "^2.5.0" + }, + "dependencies": { + "type": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", + "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "find-replace": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", + "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=", + "dev": true, + "requires": { + "array-back": "^1.0.4", + "test-value": "^2.1.0" + }, + "dependencies": { + "array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", + "dev": true, + "requires": { + "typical": "^2.6.0" + } + } + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "requires": { + "micromatch": "^4.0.2" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "follow-redirects": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", + "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "ganache-core": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", + "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", + "dev": true, + "requires": { + "abstract-leveldown": "3.0.0", + "async": "2.6.2", + "bip39": "2.5.0", + "cachedown": "1.0.0", + "clone": "2.1.2", + "debug": "3.2.6", + "encoding-down": "5.0.4", + "eth-sig-util": "3.0.0", + "ethereumjs-abi": "0.6.8", + "ethereumjs-account": "3.0.0", + "ethereumjs-block": "2.2.2", + "ethereumjs-common": "1.5.0", + "ethereumjs-tx": "2.1.2", + "ethereumjs-util": "6.2.1", + "ethereumjs-vm": "4.2.0", + "ethereumjs-wallet": "0.6.5", + "heap": "0.2.6", + "keccak": "3.0.1", + "level-sublevel": "6.6.4", + "levelup": "3.1.1", + "lodash": "4.17.20", + "lru-cache": "5.1.1", + "merkle-patricia-tree": "3.0.0", + "patch-package": "6.2.2", + "seedrandom": "3.0.1", + "source-map-support": "0.5.12", + "tmp": "0.1.0", + "web3": "1.2.11", + "web3-provider-engine": "14.2.1", + "websocket": "1.0.32" + }, + "dependencies": { + "@ethersproject/abi": { + "version": "5.0.0-beta.153", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/address": ">=5.0.0-beta.128", + "@ethersproject/bignumber": ">=5.0.0-beta.130", + "@ethersproject/bytes": ">=5.0.0-beta.129", + "@ethersproject/constants": ">=5.0.0-beta.128", + "@ethersproject/hash": ">=5.0.0-beta.128", + "@ethersproject/keccak256": ">=5.0.0-beta.127", + "@ethersproject/logger": ">=5.0.0-beta.129", + "@ethersproject/properties": ">=5.0.0-beta.131", + "@ethersproject/strings": ">=5.0.0-beta.130" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.0.8", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/networks": "^5.0.7", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/transactions": "^5.0.9", + "@ethersproject/web": "^5.0.12" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.0.10", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/abstract-provider": "^5.0.8", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7" + } + }, + "@ethersproject/address": { + "version": "5.0.9", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/rlp": "^5.0.7" + } + }, + "@ethersproject/base64": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9" + } + }, + "@ethersproject/bignumber": { + "version": "5.0.13", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.0.9", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/constants": { + "version": "5.0.8", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bignumber": "^5.0.13" + } + }, + "@ethersproject/hash": { + "version": "5.0.10", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/abstract-signer": "^5.0.10", + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "@ethersproject/keccak256": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "js-sha3": "0.5.7" + } + }, + "@ethersproject/logger": { + "version": "5.0.8", + "dev": true, + "optional": true + }, + "@ethersproject/networks": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/properties": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/rlp": { + "version": "5.0.7", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/signing-key": { + "version": "5.0.8", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "elliptic": "6.5.3" + } + }, + "@ethersproject/strings": { + "version": "5.0.8", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/transactions": { + "version": "5.0.9", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/rlp": "^5.0.7", + "@ethersproject/signing-key": "^5.0.8" + } + }, + "@ethersproject/web": { + "version": "5.0.12", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/base64": "^5.0.7", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "dev": true, + "optional": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "dev": true, + "optional": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/bn.js": { + "version": "4.11.6", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "14.14.20", + "dev": true + }, + "@types/pbkdf2": { + "version": "3.1.0", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.1", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true + }, + "abstract-leveldown": { + "version": "3.0.0", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "accepts": { + "version": "1.3.7", + "dev": true, + "optional": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "aes-js": { + "version": "3.1.2", + "dev": true, + "optional": true + }, + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-styles": { + "version": "3.2.1", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "arr-diff": { + "version": "4.0.0", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "dev": true, + "optional": true + }, + "array-unique": { + "version": "0.3.2", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "dev": true + }, + "async": { + "version": "2.6.2", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "async-eventemitter": { + "version": "0.2.4", + "dev": true, + "requires": { + "async": "^2.4.0" + } + }, + "async-limiter": { + "version": "1.0.1", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "dev": true + }, + "atob": { + "version": "2.1.2", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "dev": true + } + } + }, + "babel-core": { + "version": "6.26.3", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "json5": { + "version": "0.5.1", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + }, + "slash": { + "version": "1.0.0", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.1", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "dev": true + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-preset-env": { + "version": "1.7.0", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "dev": true + } + } + }, + "babel-register": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + }, + "dependencies": { + "source-map-support": { + "version": "0.4.18", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "babel-types": { + "version": "6.26.0", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "dev": true + } + } + }, + "babelify": { + "version": "7.3.0", + "dev": true, + "requires": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, + "babylon": { + "version": "6.18.0", + "dev": true + }, + "backoff": { + "version": "2.5.0", + "dev": true, + "requires": { + "precond": "0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "dev": true + }, + "base": { + "version": "0.11.2", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "base-x": { + "version": "3.0.8", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "dev": true + } + } + }, + "bignumber.js": { + "version": "9.0.1", + "dev": true, + "optional": true + }, + "bip39": { + "version": "2.5.0", + "dev": true, + "requires": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "blakejs": { + "version": "1.1.0", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "dev": true, + "optional": true + }, + "bn.js": { + "version": "4.11.9", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "dev": true, + "optional": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.7.0", + "dev": true, + "optional": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "dev": true, + "optional": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "dev": true, + "optional": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "5.1.3", + "dev": true, + "optional": true + } + } + }, + "browserify-sign": { + "version": "4.2.1", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "bn.js": { + "version": "5.1.3", + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "3.6.0", + "dev": true, + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "browserslist": { + "version": "3.2.8", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "bs58": { + "version": "4.0.1", + "dev": true, + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "dev": true, + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "5.7.1", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.1", + "dev": true + }, + "buffer-to-arraybuffer": { + "version": "0.0.5", + "dev": true, + "optional": true + }, + "buffer-xor": { + "version": "1.0.3", + "dev": true + }, + "bufferutil": { + "version": "4.0.3", + "dev": true, + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "bytes": { + "version": "3.1.0", + "dev": true, + "optional": true + }, + "bytewise": { + "version": "1.1.0", + "dev": true, + "requires": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "bytewise-core": { + "version": "1.2.3", + "dev": true, + "requires": { + "typewise-core": "^1.2" + } + }, + "cache-base": { + "version": "1.0.1", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cacheable-request": { + "version": "6.1.0", + "dev": true, + "optional": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "lowercase-keys": { + "version": "2.0.0", + "dev": true, + "optional": true + } + } + }, + "cachedown": { + "version": "1.0.0", + "dev": true, + "requires": { + "abstract-leveldown": "^2.4.1", + "lru-cache": "^3.2.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "lru-cache": { + "version": "3.2.0", + "dev": true, + "requires": { + "pseudomap": "^1.0.1" + } + } + } + }, + "call-bind": { + "version": "1.0.2", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caniuse-lite": { + "version": "1.0.30001174", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "checkpoint-store": { + "version": "1.1.0", + "dev": true, + "requires": { + "functional-red-black-tree": "^1.0.1" + } + }, + "chownr": { + "version": "1.1.4", + "dev": true, + "optional": true + }, + "ci-info": { + "version": "2.0.0", + "dev": true + }, + "cids": { + "version": "0.7.5", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "dependencies": { + "multicodec": { + "version": "1.0.4", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + } + } + }, + "cipher-base": { + "version": "1.0.4", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-is": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "class-utils": { + "version": "0.3.6", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "dev": true + } + } + }, + "clone": { + "version": "2.1.2", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "dev": true, + "optional": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "content-disposition": { + "version": "0.5.3", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true, + "optional": true + } + } + }, + "content-hash": { + "version": "2.5.2", + "dev": true, + "optional": true, + "requires": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "content-type": { + "version": "1.0.4", + "dev": true, + "optional": true + }, + "convert-source-map": { + "version": "1.7.0", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "cookie": { + "version": "0.4.0", + "dev": true, + "optional": true + }, + "cookie-signature": { + "version": "1.0.6", + "dev": true, + "optional": true + }, + "cookiejar": { + "version": "2.1.2", + "dev": true, + "optional": true + }, + "copy-descriptor": { + "version": "0.1.1", + "dev": true + }, + "core-js": { + "version": "2.6.12", + "dev": true + }, + "core-js-pure": { + "version": "3.8.2", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "dev": true + }, + "cors": { + "version": "2.8.5", + "dev": true, + "optional": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "create-ecdh": { + "version": "4.0.4", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "create-hash": { + "version": "1.2.0", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-fetch": { + "version": "2.2.3", + "dev": true, + "requires": { + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "dev": true, + "optional": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "d": { + "version": "1.0.1", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.2.6", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "dev": true + }, + "decompress-response": { + "version": "3.3.0", + "dev": true, + "optional": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-equal": { + "version": "1.1.1", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "dev": true, + "optional": true + }, + "deferred-leveldown": { + "version": "4.0.2", + "dev": true, + "requires": { + "abstract-leveldown": "~5.0.0", + "inherits": "^2.0.3" + }, + "dependencies": { + "abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "define-properties": { + "version": "1.1.3", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "defined": { + "version": "1.0.0", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "dev": true + }, + "depd": { + "version": "1.1.2", + "dev": true, + "optional": true + }, + "des.js": { + "version": "1.0.1", + "dev": true, + "optional": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "dev": true, + "optional": true + }, + "detect-indent": { + "version": "4.0.0", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "diffie-hellman": { + "version": "5.0.3", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dom-walk": { + "version": "0.1.2", + "dev": true + }, + "dotignore": { + "version": "0.1.2", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "duplexer3": { + "version": "0.1.4", + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "dev": true, + "optional": true + }, + "electron-to-chromium": { + "version": "1.3.636", + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "encodeurl": { + "version": "1.0.2", + "dev": true, + "optional": true + }, + "encoding": { + "version": "0.1.13", + "dev": true, + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "encoding-down": { + "version": "5.0.4", + "dev": true, + "requires": { + "abstract-leveldown": "^5.0.0", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "xtend": "^4.0.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "end-of-stream": { + "version": "1.4.4", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "errno": { + "version": "0.1.8", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "es-abstract": { + "version": "1.18.0-next.1", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "escape-html": { + "version": "1.0.3", + "dev": true, + "optional": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "dev": true + }, + "etag": { + "version": "1.8.1", + "dev": true, + "optional": true + }, + "eth-block-tracker": { + "version": "3.0.1", + "dev": true, + "requires": { + "eth-query": "^2.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.3", + "ethjs-util": "^0.1.3", + "json-rpc-engine": "^3.6.0", + "pify": "^2.3.0", + "tape": "^4.6.3" + }, + "dependencies": { + "ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "requires": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "pify": { + "version": "2.3.0", + "dev": true + } + } + }, + "eth-ens-namehash": { + "version": "2.0.8", + "dev": true, + "optional": true, + "requires": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "eth-json-rpc-infura": { + "version": "3.2.1", + "dev": true, + "requires": { + "cross-fetch": "^2.1.1", + "eth-json-rpc-middleware": "^1.5.0", + "json-rpc-engine": "^3.4.0", + "json-rpc-error": "^2.0.0" + } + }, + "eth-json-rpc-middleware": { + "version": "1.6.0", + "dev": true, + "requires": { + "async": "^2.5.0", + "eth-query": "^2.1.2", + "eth-tx-summary": "^3.1.2", + "ethereumjs-block": "^1.6.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.2", + "ethereumjs-vm": "^2.1.0", + "fetch-ponyfill": "^4.0.0", + "json-rpc-engine": "^3.6.0", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "tape": "^4.6.3" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "requires": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereum-common": { + "version": "0.2.0", + "dev": true + } + } + }, + "ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "requires": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "requires": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + } + } + }, + "eth-lib": { + "version": "0.1.29", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "eth-query": { + "version": "2.1.2", + "dev": true, + "requires": { + "json-rpc-random-id": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "eth-sig-util": { + "version": "3.0.0", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "elliptic": "^6.4.0", + "ethereumjs-abi": "0.6.5", + "ethereumjs-util": "^5.1.1", + "tweetnacl": "^1.0.0", + "tweetnacl-util": "^0.15.0" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "0.6.5", + "dev": true, + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" + }, + "dependencies": { + "ethereumjs-util": { + "version": "4.5.1", + "dev": true, + "requires": { + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.0.0" + } + } + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "eth-tx-summary": { + "version": "3.2.4", + "dev": true, + "requires": { + "async": "^2.1.2", + "clone": "^2.0.0", + "concat-stream": "^1.5.1", + "end-of-stream": "^1.1.0", + "eth-query": "^2.0.2", + "ethereumjs-block": "^1.4.1", + "ethereumjs-tx": "^1.1.1", + "ethereumjs-util": "^5.0.1", + "ethereumjs-vm": "^2.6.0", + "through2": "^2.0.3" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "requires": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereum-common": { + "version": "0.2.0", + "dev": true + } + } + }, + "ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "requires": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "requires": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + } + } + }, + "ethashjs": { + "version": "0.0.8", + "dev": true, + "requires": { + "async": "^2.1.2", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.0.2", + "miller-rabin": "^4.0.0" + }, + "dependencies": { + "bn.js": { + "version": "5.1.3", + "dev": true + }, + "buffer-xor": { + "version": "2.0.2", + "dev": true, + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-util": { + "version": "7.0.7", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + } + } + } + }, + "ethereum-bloom-filters": { + "version": "1.0.7", + "dev": true, + "optional": true, + "requires": { + "js-sha3": "^0.8.0" + }, + "dependencies": { + "js-sha3": { + "version": "0.8.0", + "dev": true, + "optional": true + } + } + }, + "ethereum-common": { + "version": "0.0.18", + "dev": true + }, + "ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "ethereumjs-abi": { + "version": "0.6.8", + "dev": true, + "requires": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "ethereumjs-account": { + "version": "3.0.0", + "dev": true, + "requires": { + "ethereumjs-util": "^6.0.0", + "rlp": "^2.2.1", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + } + } + }, + "ethereumjs-blockchain": { + "version": "4.0.4", + "dev": true, + "requires": { + "async": "^2.6.1", + "ethashjs": "~0.0.7", + "ethereumjs-block": "~2.2.2", + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.1.0", + "flow-stoplight": "^1.0.0", + "level-mem": "^3.0.1", + "lru-cache": "^5.1.1", + "rlp": "^2.2.2", + "semaphore": "^1.1.0" + } + }, + "ethereumjs-common": { + "version": "1.5.0", + "dev": true + }, + "ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "requires": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "ethereumjs-vm": { + "version": "4.2.0", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "core-js-pure": "^3.0.1", + "ethereumjs-account": "^3.0.0", + "ethereumjs-block": "^2.2.2", + "ethereumjs-blockchain": "^4.0.3", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.2", + "ethereumjs-util": "^6.2.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1", + "util.promisify": "^1.0.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + } + } + }, + "ethereumjs-wallet": { + "version": "0.6.5", + "dev": true, + "optional": true, + "requires": { + "aes-js": "^3.1.1", + "bs58check": "^2.1.2", + "ethereum-cryptography": "^0.1.3", + "ethereumjs-util": "^6.0.0", + "randombytes": "^2.0.6", + "safe-buffer": "^5.1.2", + "scryptsy": "^1.2.1", + "utf8": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "ethjs-unit": { + "version": "0.1.6", + "dev": true, + "optional": true, + "requires": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "dev": true, + "optional": true + } + } + }, + "ethjs-util": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + } + }, + "eventemitter3": { + "version": "4.0.4", + "dev": true, + "optional": true + }, + "events": { + "version": "3.2.0", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "express": { + "version": "4.17.1", + "dev": true, + "optional": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.7.0", + "dev": true, + "optional": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true, + "optional": true + } + } + }, + "ext": { + "version": "1.4.0", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.1.0", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.3.0", + "dev": true + }, + "fake-merkle-patricia-tree": { + "version": "1.0.1", + "dev": true, + "requires": { + "checkpoint-store": "^1.1.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true + }, + "fetch-ponyfill": { + "version": "4.1.0", + "dev": true, + "requires": { + "node-fetch": "~1.7.1" + }, + "dependencies": { + "is-stream": { + "version": "1.1.0", + "dev": true + }, + "node-fetch": { + "version": "1.7.3", + "dev": true, + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true, + "optional": true + } + } + }, + "find-yarn-workspace-root": { + "version": "1.2.1", + "dev": true, + "requires": { + "fs-extra": "^4.0.3", + "micromatch": "^3.1.4" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fs-extra": { + "version": "4.0.3", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "flow-stoplight": { + "version": "1.0.0", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "for-in": { + "version": "1.0.2", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "dev": true, + "optional": true + }, + "fragment-cache": { + "version": "0.2.1", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "dev": true, + "optional": true + }, + "fs-extra": { + "version": "7.0.1", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "dev": true + }, + "get-intrinsic": { + "version": "1.0.2", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stream": { + "version": "5.2.0", + "dev": true, + "optional": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.3", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global": { + "version": "4.4.0", + "dev": true, + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "got": { + "version": "9.6.0", + "dev": true, + "optional": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "get-stream": { + "version": "4.1.0", + "dev": true, + "optional": true, + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "graceful-fs": { + "version": "4.2.4", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "dev": true + }, + "has-symbol-support-x": { + "version": "1.4.2", + "dev": true, + "optional": true + }, + "has-symbols": { + "version": "1.0.1", + "dev": true + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "dev": true, + "optional": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-value": { + "version": "1.0.0", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "hash.js": { + "version": "1.1.7", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "heap": { + "version": "0.2.6", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "home-or-tmp": { + "version": "2.0.0", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "dev": true, + "optional": true + }, + "http-errors": { + "version": "1.7.2", + "dev": true, + "optional": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "dev": true, + "optional": true + } + } + }, + "http-https": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "http-signature": { + "version": "1.2.0", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "idna-uts46-hx": { + "version": "2.3.1", + "dev": true, + "optional": true, + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "dev": true, + "optional": true + } + } + }, + "ieee754": { + "version": "1.2.1", + "dev": true + }, + "immediate": { + "version": "3.2.3", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "ipaddr.js": { + "version": "1.9.1", + "dev": true, + "optional": true + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-arguments": { + "version": "1.1.0", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.2", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-date-object": { + "version": "1.0.2", + "dev": true + }, + "is-descriptor": { + "version": "1.0.2", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-finite": { + "version": "1.1.0", + "dev": true + }, + "is-fn": { + "version": "1.0.0", + "dev": true + }, + "is-function": { + "version": "1.0.2", + "dev": true + }, + "is-hex-prefixed": { + "version": "1.0.0", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "dev": true + }, + "is-object": { + "version": "1.0.2", + "dev": true, + "optional": true + }, + "is-plain-obj": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "is-plain-object": { + "version": "2.0.4", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.1", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-retry-allowed": { + "version": "1.2.0", + "dev": true, + "optional": true + }, + "is-symbol": { + "version": "1.0.3", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "dev": true + }, + "isurl": { + "version": "1.0.0", + "dev": true, + "optional": true, + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "js-sha3": { + "version": "0.5.7", + "dev": true, + "optional": true + }, + "js-tokens": { + "version": "4.0.0", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "dev": true, + "optional": true + }, + "json-rpc-engine": { + "version": "3.8.0", + "dev": true, + "requires": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + }, + "json-rpc-error": { + "version": "2.0.0", + "dev": true, + "requires": { + "inherits": "^2.0.1" + } + }, + "json-rpc-random-id": { + "version": "1.0.1", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keccak": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "keyv": { + "version": "3.1.0", + "dev": true, + "optional": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "kind-of": { + "version": "6.0.3", + "dev": true + }, + "klaw-sync": { + "version": "6.0.0", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11" + } + }, + "level-codec": { + "version": "9.0.2", + "dev": true, + "requires": { + "buffer": "^5.6.0" + } + }, + "level-errors": { + "version": "2.0.1", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "2.0.3", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.5", + "xtend": "^4.0.0" + } + }, + "level-mem": { + "version": "3.0.1", + "dev": true, + "requires": { + "level-packager": "~4.0.0", + "memdown": "~3.0.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "5.0.0", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "3.0.0", + "dev": true, + "requires": { + "abstract-leveldown": "~5.0.0", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "level-packager": { + "version": "4.0.1", + "dev": true, + "requires": { + "encoding-down": "~5.0.0", + "levelup": "^3.0.0" + } + }, + "level-post": { + "version": "1.0.7", + "dev": true, + "requires": { + "ltgt": "^2.1.2" + } + }, + "level-sublevel": { + "version": "6.6.4", + "dev": true, + "requires": { + "bytewise": "~1.1.0", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "level-iterator-stream": "^2.0.3", + "ltgt": "~2.1.1", + "pull-defer": "^0.2.2", + "pull-level": "^2.0.3", + "pull-stream": "^3.6.8", + "typewiselite": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "level-ws": { + "version": "1.0.0", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.8", + "xtend": "^4.0.1" + } + }, + "levelup": { + "version": "3.1.1", + "dev": true, + "requires": { + "deferred-leveldown": "~4.0.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~3.0.0", + "xtend": "~4.0.0" + }, + "dependencies": { + "level-iterator-stream": { + "version": "3.0.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "xtend": "^4.0.0" + } + } + } + }, + "lodash": { + "version": "4.17.20", + "dev": true + }, + "looper": { + "version": "2.0.0", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "lru-cache": { + "version": "5.1.1", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "ltgt": { + "version": "2.1.3", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "dev": true, + "optional": true + }, + "merge-descriptors": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "merkle-patricia-tree": { + "version": "3.0.0", + "dev": true, + "requires": { + "async": "^2.6.1", + "ethereumjs-util": "^5.2.0", + "level-mem": "^3.0.1", + "level-ws": "^1.0.0", + "readable-stream": "^3.0.6", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "methods": { + "version": "1.1.2", + "dev": true, + "optional": true + }, + "miller-rabin": { + "version": "4.0.1", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "dev": true, + "optional": true + }, + "mime-db": { + "version": "1.45.0", + "dev": true + }, + "mime-types": { + "version": "2.1.28", + "dev": true, + "requires": { + "mime-db": "1.45.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "min-document": { + "version": "2.19.0", + "dev": true, + "requires": { + "dom-walk": "^0.1.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "dev": true + }, + "minizlib": { + "version": "1.3.3", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "mixin-deep": { + "version": "1.3.2", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + } + }, + "mkdirp": { + "version": "0.5.5", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mkdirp-promise": { + "version": "5.0.1", + "dev": true, + "optional": true, + "requires": { + "mkdirp": "*" + } + }, + "mock-fs": { + "version": "4.13.0", + "dev": true, + "optional": true + }, + "ms": { + "version": "2.1.3", + "dev": true + }, + "multibase": { + "version": "0.6.1", + "dev": true, + "optional": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "multicodec": { + "version": "0.5.7", + "dev": true, + "optional": true, + "requires": { + "varint": "^5.0.0" + } + }, + "multihashes": { + "version": "0.4.21", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + }, + "dependencies": { + "multibase": { + "version": "0.7.0", + "dev": true, + "optional": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + } + } + }, + "nano-json-stream-parser": { + "version": "0.1.2", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "negotiator": { + "version": "0.6.2", + "dev": true, + "optional": true + }, + "next-tick": { + "version": "1.0.0", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "dev": true + }, + "node-addon-api": { + "version": "2.0.2", + "bundled": true, + "dev": true + }, + "node-fetch": { + "version": "2.1.2", + "dev": true + }, + "node-gyp-build": { + "version": "4.2.3", + "bundled": true, + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "dev": true, + "optional": true + }, + "number-to-bn": { + "version": "1.7.0", + "dev": true, + "optional": true, + "requires": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "dev": true, + "optional": true + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.9.0", + "dev": true + }, + "object-is": { + "version": "1.1.4", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.2", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.1", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "object.pick": { + "version": "1.3.0", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "oboe": { + "version": "2.1.4", + "dev": true, + "optional": true, + "requires": { + "http-https": "^1.0.0" + } + }, + "on-finished": { + "version": "2.3.0", + "dev": true, + "optional": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "p-timeout": { + "version": "1.2.1", + "dev": true, + "optional": true, + "requires": { + "p-finally": "^1.0.0" + }, + "dependencies": { + "p-finally": { + "version": "1.0.0", + "dev": true, + "optional": true + } + } + }, + "parse-asn1": { + "version": "5.1.6", + "dev": true, + "optional": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-headers": { + "version": "2.0.3", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "dev": true, + "optional": true + }, + "pascalcase": { + "version": "0.1.1", + "dev": true + }, + "patch-package": { + "version": "6.2.2", + "dev": true, + "requires": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^1.2.1", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "dev": true + }, + "semver": { + "version": "5.7.1", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "dev": true + }, + "slash": { + "version": "2.0.0", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "which": { + "version": "1.3.1", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "path-is-absolute": { + "version": "1.0.1", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "dev": true, + "optional": true + }, + "pbkdf2": { + "version": "3.1.1", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "dev": true + }, + "precond": { + "version": "0.2.3", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "dev": true, + "optional": true + }, + "private": { + "version": "0.1.8", + "dev": true + }, + "process": { + "version": "0.11.10", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "dev": true + }, + "promise-to-callback": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-fn": "^1.0.0", + "set-immediate-shim": "^1.0.1" + } + }, + "proxy-addr": { + "version": "2.0.6", + "dev": true, + "optional": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "dev": true + }, + "psl": { + "version": "1.8.0", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pull-cat": { + "version": "1.1.11", + "dev": true + }, + "pull-defer": { + "version": "0.2.3", + "dev": true + }, + "pull-level": { + "version": "2.0.4", + "dev": true, + "requires": { + "level-post": "^1.0.7", + "pull-cat": "^1.1.9", + "pull-live": "^1.0.1", + "pull-pushable": "^2.0.0", + "pull-stream": "^3.4.0", + "pull-window": "^2.1.4", + "stream-to-pull-stream": "^1.7.1" + } + }, + "pull-live": { + "version": "1.0.1", + "dev": true, + "requires": { + "pull-cat": "^1.1.9", + "pull-stream": "^3.4.0" + } + }, + "pull-pushable": { + "version": "2.2.0", + "dev": true + }, + "pull-stream": { + "version": "3.6.14", + "dev": true + }, + "pull-window": { + "version": "2.1.4", + "dev": true, + "requires": { + "looper": "^2.0.0" + } + }, + "pump": { + "version": "3.0.0", + "dev": true, + "optional": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "dev": true + }, + "qs": { + "version": "6.5.2", + "dev": true + }, + "query-string": { + "version": "5.1.1", + "dev": true, + "optional": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "randombytes": { + "version": "2.1.0", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "dev": true, + "optional": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "dev": true, + "optional": true + }, + "raw-body": { + "version": "2.4.0", + "dev": true, + "optional": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "regenerate": { + "version": "1.4.2", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + }, + "regexpu-core": { + "version": "2.0.0", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "dev": true + } + } + }, + "repeat-element": { + "version": "1.1.3", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.2", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "resolve-url": { + "version": "0.2.1", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "dev": true, + "optional": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "resumer": { + "version": "0.0.0", + "dev": true, + "requires": { + "through": "~2.3.4" + } + }, + "ret": { + "version": "0.1.15", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rlp": { + "version": "2.2.6", + "dev": true, + "requires": { + "bn.js": "^4.11.1" + } + }, + "rustbn.js": { + "version": "0.2.0", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "dev": true + }, + "safe-event-emitter": { + "version": "1.0.1", + "dev": true, + "requires": { + "events": "^3.0.0" + } + }, + "safe-regex": { + "version": "1.1.0", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "dev": true + }, + "scrypt-js": { + "version": "3.0.1", + "dev": true + }, + "scryptsy": { + "version": "1.2.1", + "dev": true, + "optional": true, + "requires": { + "pbkdf2": "^3.0.3" + } + }, + "secp256k1": { + "version": "4.0.2", + "dev": true, + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "seedrandom": { + "version": "3.0.1", + "dev": true + }, + "semaphore": { + "version": "1.1.0", + "dev": true + }, + "send": { + "version": "0.17.1", + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "dev": true, + "optional": true + } + } + }, + "ms": { + "version": "2.1.1", + "dev": true, + "optional": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "dev": true, + "optional": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "servify": { + "version": "0.1.12", + "dev": true, + "optional": true, + "requires": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + } + }, + "set-immediate-shim": { + "version": "1.0.1", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + } + } + }, + "setimmediate": { + "version": "1.0.5", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "dev": true, + "optional": true + }, + "sha.js": { + "version": "2.4.11", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "simple-concat": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "simple-get": { + "version": "2.8.1", + "dev": true, + "optional": true, + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.12", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sshpk": { + "version": "1.16.1", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "dev": true + } + } + }, + "static-extend": { + "version": "0.1.2", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "dev": true + } + } + }, + "statuses": { + "version": "1.5.0", + "dev": true, + "optional": true + }, + "stream-to-pull-stream": { + "version": "1.7.3", + "dev": true, + "requires": { + "looper": "^3.0.0", + "pull-stream": "^3.2.3" + }, + "dependencies": { + "looper": { + "version": "3.0.0", + "dev": true + } + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "string_decoder": { + "version": "1.1.1", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true + } + } + }, + "string.prototype.trim": { + "version": "1.2.3", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "strip-hex-prefix": { + "version": "1.0.0", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "swarm-js": { + "version": "0.1.40", + "dev": true, + "optional": true, + "requires": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "get-stream": { + "version": "3.0.0", + "dev": true, + "optional": true + }, + "got": { + "version": "7.1.0", + "dev": true, + "optional": true, + "requires": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "dev": true, + "optional": true + }, + "p-cancelable": { + "version": "0.3.0", + "dev": true, + "optional": true + }, + "prepend-http": { + "version": "1.0.4", + "dev": true, + "optional": true + }, + "url-parse-lax": { + "version": "1.0.0", + "dev": true, + "optional": true, + "requires": { + "prepend-http": "^1.0.1" + } + } + } + }, + "tape": { + "version": "4.13.3", + "dev": true, + "requires": { + "deep-equal": "~1.1.1", + "defined": "~1.0.0", + "dotignore": "~0.1.2", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.6", + "has": "~1.0.3", + "inherits": "~2.0.4", + "is-regex": "~1.0.5", + "minimist": "~1.2.5", + "object-inspect": "~1.7.0", + "resolve": "~1.17.0", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.2.1", + "through": "~2.3.8" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "is-regex": { + "version": "1.0.5", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "tar": { + "version": "4.4.13", + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "dependencies": { + "fs-minipass": { + "version": "1.2.7", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "minipass": { + "version": "2.9.0", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "through": { + "version": "2.3.8", + "dev": true + }, + "through2": { + "version": "2.0.5", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timed-out": { + "version": "4.0.1", + "dev": true, + "optional": true + }, + "tmp": { + "version": "0.1.0", + "dev": true, + "requires": { + "rimraf": "^2.6.3" + } + }, + "to-object-path": { + "version": "0.3.0", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-readable-stream": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "to-regex": { + "version": "3.0.2", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "tough-cookie": { + "version": "2.5.0", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "trim-right": { + "version": "1.0.1", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "dev": true + }, + "tweetnacl-util": { + "version": "0.15.1", + "dev": true + }, + "type": { + "version": "1.2.0", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "dev": true, + "optional": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typewise": { + "version": "1.0.3", + "dev": true, + "requires": { + "typewise-core": "^1.2.0" + } + }, + "typewise-core": { + "version": "1.2.0", + "dev": true + }, + "typewiselite": { + "version": "1.0.0", + "dev": true + }, + "ultron": { + "version": "1.1.1", + "dev": true, + "optional": true + }, + "underscore": { + "version": "1.9.1", + "dev": true, + "optional": true + }, + "union-value": { + "version": "1.0.1", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "dev": true + }, + "unorm": { + "version": "1.6.0", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "unset-value": { + "version": "1.0.0", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "dev": true + } + } + }, + "uri-js": { + "version": "4.4.1", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "dev": true + }, + "url-parse-lax": { + "version": "3.0.0", + "dev": true, + "optional": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "url-set-query": { + "version": "1.0.0", + "dev": true, + "optional": true + }, + "url-to-options": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "use": { + "version": "3.1.1", + "dev": true + }, + "utf-8-validate": { + "version": "5.0.4", + "dev": true, + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "utf8": { + "version": "3.0.0", + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "dev": true + }, + "util.promisify": { + "version": "1.1.1", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "for-each": "^0.3.3", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.1" + } + }, + "utils-merge": { + "version": "1.0.1", + "dev": true, + "optional": true + }, + "uuid": { + "version": "3.4.0", + "dev": true + }, + "varint": { + "version": "5.0.2", + "dev": true, + "optional": true + }, + "vary": { + "version": "1.1.2", + "dev": true, + "optional": true + }, + "verror": { + "version": "1.10.0", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "web3": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "web3-bzz": "1.2.11", + "web3-core": "1.2.11", + "web3-eth": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-shh": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-bzz": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40", + "underscore": "1.9.1" + }, + "dependencies": { + "@types/node": { + "version": "12.19.12", + "dev": true, + "optional": true + } + } + }, + "web3-core": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-requestmanager": "1.2.11", + "web3-utils": "1.2.11" + }, + "dependencies": { + "@types/node": { + "version": "12.19.12", + "dev": true, + "optional": true + } + } + }, + "web3-core-helpers": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "underscore": "1.9.1", + "web3-eth-iban": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-core-method": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/transactions": "^5.0.0-beta.135", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-core-promievent": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "eventemitter3": "4.0.4" + } + }, + "web3-core-requestmanager": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-providers-http": "1.2.11", + "web3-providers-ipc": "1.2.11", + "web3-providers-ws": "1.2.11" + } + }, + "web3-core-subscriptions": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + } + }, + "web3-eth": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-accounts": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-eth-ens": "1.2.11", + "web3-eth-iban": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-eth-abi": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/abi": "5.0.0-beta.153", + "underscore": "1.9.1", + "web3-utils": "1.2.11" + } + }, + "web3-eth-accounts": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-common": "^1.3.2", + "ethereumjs-tx": "^2.1.1", + "scrypt-js": "^3.0.1", + "underscore": "1.9.1", + "uuid": "3.3.2", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "uuid": { + "version": "3.3.2", + "dev": true, + "optional": true + } + } + }, + "web3-eth-contract": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@types/bn.js": "^4.11.5", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-eth-ens": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-eth-iban": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.9", + "web3-utils": "1.2.11" + } + }, + "web3-eth-personal": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "@types/node": "^12.12.6", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + }, + "dependencies": { + "@types/node": { + "version": "12.19.12", + "dev": true, + "optional": true + } + } + }, + "web3-net": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + } + }, + "web3-provider-engine": { + "version": "14.2.1", + "dev": true, + "requires": { + "async": "^2.5.0", + "backoff": "^2.5.0", + "clone": "^2.0.0", + "cross-fetch": "^2.1.0", + "eth-block-tracker": "^3.0.0", + "eth-json-rpc-infura": "^3.1.0", + "eth-sig-util": "3.0.0", + "ethereumjs-block": "^1.2.2", + "ethereumjs-tx": "^1.2.0", + "ethereumjs-util": "^5.1.5", + "ethereumjs-vm": "^2.3.4", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "readable-stream": "^2.2.9", + "request": "^2.85.0", + "semaphore": "^1.0.3", + "ws": "^5.1.1", + "xhr": "^2.2.0", + "xtend": "^4.0.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.6.3", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "1.2.2", + "dev": true, + "requires": { + "abstract-leveldown": "~2.6.0" + } + }, + "eth-sig-util": { + "version": "1.4.2", + "dev": true, + "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "ethereumjs-util": "^5.1.1" + } + }, + "ethereumjs-account": { + "version": "2.0.5", + "dev": true, + "requires": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-block": { + "version": "1.7.1", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereum-common": { + "version": "0.2.0", + "dev": true + } + } + }, + "ethereumjs-tx": { + "version": "1.3.7", + "dev": true, + "requires": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "ethereumjs-vm": { + "version": "2.6.0", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "ethereumjs-block": { + "version": "2.2.2", + "dev": true, + "requires": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "dev": true, + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + } + } + }, + "ethereumjs-tx": { + "version": "2.1.2", + "dev": true, + "requires": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, + "isarray": { + "version": "0.0.1", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "dev": true, + "requires": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "xtend": { + "version": "2.1.2", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, + "merkle-patricia-tree": { + "version": "2.3.2", + "dev": true, + "requires": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "dev": true + } + } + }, + "object-keys": { + "version": "0.4.0", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "semver": { + "version": "5.4.1", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "dev": true + }, + "ws": { + "version": "5.2.2", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "web3-providers-http": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "web3-core-helpers": "1.2.11", + "xhr2-cookies": "1.1.0" + } + }, + "web3-providers-ipc": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "oboe": "2.1.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + } + }, + "web3-providers-ws": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "websocket": "^1.0.31" + } + }, + "web3-shh": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-net": "1.2.11" + } + }, + "web3-utils": { + "version": "1.2.11", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.9.1", + "utf8": "3.0.0" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "dev": true, + "optional": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + } + } + }, + "websocket": { + "version": "1.0.32", + "dev": true, + "requires": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "whatwg-fetch": { + "version": "2.0.4", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "dev": true + }, + "ws": { + "version": "3.3.3", + "dev": true, + "optional": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "dev": true, + "optional": true + } + } + }, + "xhr": { + "version": "2.6.0", + "dev": true, + "requires": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xhr-request": { + "version": "1.1.0", + "dev": true, + "optional": true, + "requires": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "xhr-request-promise": { + "version": "0.1.3", + "dev": true, + "optional": true, + "requires": { + "xhr-request": "^1.1.0" + } + }, + "xhr2-cookies": { + "version": "1.1.0", + "dev": true, + "optional": true, + "requires": { + "cookiejar": "^2.1.1" + } + }, + "xtend": { + "version": "4.0.2", + "dev": true + }, + "yaeti": { + "version": "0.0.6", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "dev": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "ghost-testrpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", + "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "globals": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "hardhat": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.5.tgz", + "integrity": "sha512-UIhjLQmccFOH87ODfFnVatI5vpwycsJ+D5+gmgOQNxUWp4c0ZenkeCE4yDEQ0tQm/zc/vz/mpskULz4aSFsPAg==", + "dev": true, + "requires": { + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/blockchain": "^5.5.2", + "@ethereumjs/common": "^2.6.4", + "@ethereumjs/tx": "^3.5.1", + "@ethereumjs/vm": "^5.9.0", + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@sentry/node": "^5.18.1", + "@solidity-parser/parser": "^0.14.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "abort-controller": "^3.0.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^0.1.2", + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^7.1.4", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "^7.1.3", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "lodash": "^4.17.11", + "merkle-patricia-tree": "^4.2.4", + "mnemonist": "^0.38.0", + "mocha": "^9.2.0", + "p-map": "^4.0.0", + "qs": "^6.7.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "slash": "^3.0.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "true-case-path": "^2.2.1", + "tsort": "0.0.1", + "undici": "^4.14.1", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "dev": true, + "requires": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "hardhat-contract-sizer": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.5.1.tgz", + "integrity": "sha512-28yRb73e30aBVaZOOHTlHZFIdIasA/iFunIehrUviIJTubvdQjtSiQUo2wexHFtt71mQeMPP8qjw2sdbgatDnQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "cli-table3": "^0.6.0" + }, + "dependencies": { + "cli-table3": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "hardhat-dependency-compiler": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.1.3.tgz", + "integrity": "sha512-bCDqsOxGST6WkbMvj4lPchYWidNSSBm5CFnkyAex1T11cGmr9otZTGl81W6f9pmrtBXbKCvr3OSuNJ6Q394sAw==", + "dev": true, + "requires": {} + }, + "hardhat-gas-reporter": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", + "integrity": "sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g==", + "dev": true, + "requires": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.24", + "sha1": "^1.1.1" + } + }, + "hardhat-log-remover": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hardhat-log-remover/-/hardhat-log-remover-2.0.2.tgz", + "integrity": "sha512-TvEWOisQmZUZ7Mlb7s4XYS/MxgZzjFJSjDI8v3uTcrD6aaXy1QtomW6D6WNsISEWtwwRlSntOGpHQwFjrz2MCw==", + "dev": true, + "requires": {} + }, + "hardhat-spdx-license-identifier": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hardhat-spdx-license-identifier/-/hardhat-spdx-license-identifier-2.0.3.tgz", + "integrity": "sha512-G4u4I1md0tWaitX6Os7Nq9sYZ/CFdR+ibm7clCksGJ4yrtdHEZxgLjWpJ0WiALF9SoFKt03PwCe9lczDQ/5ADA==", + "dev": true, + "requires": {} + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", + "dev": true + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "dev": true, + "requires": { + "punycode": "2.1.0" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "dev": true + }, + "immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dev": true, + "requires": { + "fp-ts": "^1.0.0" + } + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", + "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonschema": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", + "dev": true + }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "dev": true, + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "level-codec": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "dev": true, + "requires": { + "buffer": "^5.6.0" + } + }, + "level-concat-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "dev": true + }, + "level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + } + }, + "level-mem": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", + "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", + "dev": true, + "requires": { + "level-packager": "^5.0.3", + "memdown": "^5.0.0" + } + }, + "level-packager": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "dev": true, + "requires": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + } + }, + "level-supports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "dev": true, + "requires": { + "xtend": "^4.0.2" + } + }, + "level-ws": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", + "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.0", + "xtend": "^4.0.1" + } + }, + "levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "dev": true, + "requires": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true + }, + "mcl-wasm": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", + "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "memdown": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", + "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", + "dev": true, + "requires": { + "abstract-leveldown": "~6.2.1", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "immediate": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", + "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", + "dev": true + } + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "merkle-patricia-tree": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz", + "integrity": "sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w==", + "dev": true, + "requires": { + "@types/levelup": "^4.3.0", + "ethereumjs-util": "^7.1.4", + "level-mem": "^5.0.1", + "level-ws": "^2.0.0", + "readable-stream": "^3.6.0", + "semaphore-async-await": "^1.5.1" + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dev": true, + "requires": { + "dom-walk": "^0.1.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", + "dev": true, + "requires": { + "mkdirp": "*" + } + }, + "mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dev": true, + "requires": { + "obliterator": "^2.0.0" + } + }, + "mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "mock-fs": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", + "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "dev": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "dev": true, + "requires": { + "varint": "^5.0.0" + } + }, + "multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + }, + "dependencies": { + "multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "dev": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + } + } + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nano-json-stream-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", + "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", + "dev": true + }, + "nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true + }, + "node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "dev": true + }, + "nofilter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", + "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "dev": true, + "requires": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", + "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", + "dev": true + }, + "oboe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", + "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", + "dev": true, + "requires": { + "http-https": "^1.0.0" + } + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "dev": true + }, + "parse-headers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "patch-package": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", + "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", + "dev": true, + "requires": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "postinstall-postinstall": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", + "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "prettier": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", + "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "prettier-plugin-solidity": { + "version": "1.0.0-beta.19", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz", + "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==", + "dev": true, + "requires": { + "@solidity-parser/parser": "^0.14.0", + "emoji-regex": "^10.0.0", + "escape-string-regexp": "^4.0.0", + "semver": "^7.3.5", + "solidity-comments-extractor": "^0.0.7", + "string-width": "^4.2.3" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + } + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "dev": true, + "requires": { + "asap": "~2.0.6" + } + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true + }, + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "dependencies": { + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "recursive-readdir": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", + "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "dev": true, + "requires": { + "minimatch": "3.0.4" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=", + "dev": true, + "requires": { + "req-from": "^2.0.0" + } + }, + "req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dev": true, + "requires": { + "bn.js": "^5.2.0" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + } + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", + "dev": true + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sc-istanbul": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", + "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", + "dev": true, + "requires": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "dev": true, + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "semaphore-async-await": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", + "integrity": "sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo=", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "servify": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", + "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "dev": true, + "requires": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=", + "dev": true, + "requires": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true + }, + "simple-get": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "dev": true, + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + } + }, + "solc": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", + "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", + "dev": true, + "requires": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "solhint": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.7.tgz", + "integrity": "sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ==", + "dev": true, + "requires": { + "@solidity-parser/parser": "^0.14.1", + "ajv": "^6.6.1", + "antlr4": "4.7.1", + "ast-parents": "0.0.1", + "chalk": "^2.4.2", + "commander": "2.18.0", + "cosmiconfig": "^5.0.7", + "eslint": "^5.6.0", + "fast-diff": "^1.1.2", + "glob": "^7.1.3", + "ignore": "^4.0.6", + "js-yaml": "^3.12.0", + "lodash": "^4.17.11", + "prettier": "^1.14.3", + "semver": "^6.3.0" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", + "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true, + "optional": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "solidity-comments-extractor": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", + "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", + "dev": true + }, + "solidity-coverage": { + "version": "0.7.21", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.21.tgz", + "integrity": "sha512-O8nuzJ9yXiKUx3NdzVvHrUW0DxoNVcGzq/I7NzewNO9EZE3wYAQ4l8BwcnV64r4aC/HB6Vnw/q2sF0BQHv/3fg==", + "dev": true, + "requires": { + "@solidity-parser/parser": "^0.14.0", + "@truffle/provider": "^0.2.24", + "chalk": "^2.4.2", + "death": "^1.1.0", + "detect-port": "^1.3.0", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.15", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "solmate": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/solmate/-/solmate-6.6.1.tgz", + "integrity": "sha512-WHvRXQvGtgR6R9nmkDTz/d+oULMqf/D33rlzQyadTX2SbuTmaW7ToEjGjGtWUVCQwZsZ/JP3vbOEVv7fB50btg==" + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + } + } + }, + "stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dev": true, + "requires": { + "type-fest": "^0.7.1" + }, + "dependencies": { + "type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "dev": true + } + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "swarm-js": { + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", + "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "dev": true, + "requires": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + } + } + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "requires": { + "get-port": "^3.1.0" + } + }, + "table": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "requires": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + } + }, + "test-value": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", + "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", + "dev": true, + "requires": { + "array-back": "^1.0.3", + "typical": "^2.6.0" + }, + "dependencies": { + "array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", + "dev": true, + "requires": { + "typical": "^2.6.0" + } + } + } + }, + "testrpc": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", + "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "requires": { + "tmp": "^0.2.0" + }, + "dependencies": { + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + } + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "true-case-path": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", + "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==", + "dev": true + }, + "ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "dev": true, + "requires": {} + }, + "ts-generator": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz", + "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==", + "dev": true, + "requires": { + "@types/mkdirp": "^0.5.2", + "@types/prettier": "^2.1.1", + "@types/resolve": "^0.0.8", + "chalk": "^2.4.1", + "glob": "^7.1.2", + "mkdirp": "^0.5.1", + "prettier": "^2.1.2", + "resolve": "^1.8.1", + "ts-essentials": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "ts-essentials": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", + "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", + "dev": true + } + } + }, + "ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.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.0", + "yn": "3.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typechain": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-5.2.0.tgz", + "integrity": "sha512-0INirvQ+P+MwJOeMct+WLkUE4zov06QxC96D+i3uGFEHoiSkZN70MKDQsaj8zkL86wQwByJReI2e7fOUwECFuw==", + "dev": true, + "requires": { + "@types/prettier": "^2.1.1", + "command-line-args": "^4.0.7", + "debug": "^4.1.1", + "fs-extra": "^7.0.0", + "glob": "^7.1.6", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.1.2", + "ts-essentials": "^7.0.1" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "dev": true + }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + }, + "uglify-js": { + "version": "3.15.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", + "integrity": "sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==", + "dev": true, + "optional": true + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "undici": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz", + "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "url-set-query": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", + "dev": true + }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true + }, + "utf-8-validate": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", + "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", + "dev": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true + }, + "util": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "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 + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "web3": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", + "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", + "dev": true, + "requires": { + "web3-bzz": "1.5.3", + "web3-core": "1.5.3", + "web3-eth": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-shh": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-bzz": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", + "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", + "dev": true, + "requires": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40" + } + }, + "web3-core": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", + "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-requestmanager": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-core-helpers": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", + "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", + "dev": true, + "requires": { + "web3-eth-iban": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-core-method": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", + "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.4.0", + "@ethersproject/transactions": "^5.0.0-beta.135", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-core-promievent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", + "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", + "dev": true, + "requires": { + "eventemitter3": "4.0.4" + } + }, + "web3-core-requestmanager": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", + "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", + "dev": true, + "requires": { + "util": "^0.12.0", + "web3-core-helpers": "1.5.3", + "web3-providers-http": "1.5.3", + "web3-providers-ipc": "1.5.3", + "web3-providers-ws": "1.5.3" + } + }, + "web3-core-subscriptions": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", + "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", + "dev": true, + "requires": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3" + } + }, + "web3-eth": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", + "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", + "dev": true, + "requires": { + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-accounts": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-eth-ens": "1.5.3", + "web3-eth-iban": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-abi": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", + "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", + "dev": true, + "requires": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.5.3" + }, + "dependencies": { + "@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "requires": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-accounts": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", + "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", + "dev": true, + "requires": { + "@ethereumjs/common": "^2.3.0", + "@ethereumjs/tx": "^3.2.1", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-contract": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", + "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.5", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-ens": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", + "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", + "dev": true, + "requires": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-iban": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", + "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "web3-utils": "1.5.3" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-eth-personal": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", + "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", + "dev": true, + "requires": { + "@types/node": "^12.12.6", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-net": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", + "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", + "dev": true, + "requires": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } + } + }, + "web3-providers-http": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", + "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", + "dev": true, + "requires": { + "web3-core-helpers": "1.5.3", + "xhr2-cookies": "1.1.0" + } + }, + "web3-providers-ipc": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", + "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", + "dev": true, + "requires": { + "oboe": "2.1.5", + "web3-core-helpers": "1.5.3" + } + }, + "web3-providers-ws": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", + "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", + "dev": true, + "requires": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3", + "websocket": "^1.0.32" + } + }, + "web3-shh": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", + "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", + "dev": true, + "requires": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-net": "1.5.3" + } + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "websocket": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", + "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "dev": true, + "requires": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "which-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", + "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.9" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "requires": {} + }, + "xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "dev": true, + "requires": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "dev": true, + "requires": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "xhr-request-promise": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", + "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", + "dev": true, + "requires": { + "xhr-request": "^1.1.0" + } + }, + "xhr2-cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", + "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "dev": true, + "requires": { + "cookiejar": "^2.1.1" + } + }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/lens-protocol/modules/package.json b/lens-protocol/modules/package.json new file mode 100644 index 0000000..14c277b --- /dev/null +++ b/lens-protocol/modules/package.json @@ -0,0 +1,57 @@ +{ + "name": "hardhat-project", + "scripts": { + "test": "npm run compile && TRACK_GAS=true hardhat test", + "quick-test": "hardhat test", + "coverage": "npm run compile && SKIP_LOAD=true hardhat coverage", + "compile": "SKIP_LOAD=true hardhat clean && SKIP_LOAD=true hardhat compile" + }, + "engines": { + "node": ">=8.3.0" + }, + "devDependencies": { + "@aave/core-v3": "1.16.2", + "@ethersproject/abi": "^5.6.3", + "@ethersproject/bignumber": "^5.6.2", + "@nomiclabs/hardhat-ethers": "^2.0.6", + "@nomiclabs/hardhat-etherscan": "^3.0.3", + "@nomiclabs/hardhat-waffle": "^2.0.3", + "@openzeppelin/contracts": "^4.7.3", + "@typechain/ethers-v5": "^7.2.0", + "@typechain/hardhat": "^2.3.1", + "@types/chai": "^4.3.1", + "@types/mocha": "^9.1.1", + "@types/node": "^12.20.52", + "@typescript-eslint/eslint-plugin": "^4.33.0", + "@typescript-eslint/parser": "^4.33.0", + "chai": "^4.3.6", + "dotenv": "^10.0.0", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.5.0", + "eslint-config-standard": "^16.0.3", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-promise": "^5.2.0", + "ethereum-waffle": "^3.4.4", + "ethers": "^5.6.6", + "hardhat": "^2.9.5", + "hardhat-contract-sizer": "^2.5.1", + "hardhat-dependency-compiler": "^1.1.3", + "hardhat-gas-reporter": "^1.0.8", + "hardhat-log-remover": "^2.0.2", + "hardhat-spdx-license-identifier": "^2.0.3", + "prettier": "^2.6.2", + "prettier-plugin-solidity": "^1.0.0-beta.13", + "solhint": "^3.3.7", + "solidity-coverage": "^0.7.21", + "ts-node": "^10.7.0", + "typechain": "^5.2.0", + "typescript": "^4.6.4" + }, + "dependencies": { + "@aave/lens-protocol": "^1.0.2", + "@openzeppelin/contracts": "^4.7.3", + "solmate": "^6.6.1" + } +} diff --git a/lens-protocol/modules/remappings.txt b/lens-protocol/modules/remappings.txt new file mode 100644 index 0000000..19c009f --- /dev/null +++ b/lens-protocol/modules/remappings.txt @@ -0,0 +1,4 @@ +ds-test/=lib/forge-std/lib/ds-test/src/ +forge-std/=lib/forge-std/src/ +@aave/=node_modules/@aave/ +@openzeppelin/=node_modules/@openzeppelin/ \ No newline at end of file diff --git a/lens-protocol/modules/script/deploy-module.s.sol b/lens-protocol/modules/script/deploy-module.s.sol new file mode 100644 index 0000000..f0d567d --- /dev/null +++ b/lens-protocol/modules/script/deploy-module.s.sol @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import '../lib/forge-std/src/Script.sol'; +import '../lib/forge-std/src/StdJson.sol'; +import {StepwiseCollectModule} from '../contracts/collect/StepwiseCollectModule.sol'; +import {MultirecipientFeeCollectModule} from '../contracts/collect/MultirecipientFeeCollectModule.sol'; +import {AaveFeeCollectModule} from '../contracts/collect/AaveFeeCollectModule.sol'; +import {ERC4626FeeCollectModule} from '../contracts/collect/ERC4626FeeCollectModule.sol'; +import {PartialCarbonRetirementCollectModule} from '../contracts/collect/PartialCarbonRetirementCollectModule.sol'; +import {PartialCarbonRetirementCollectModule} from '../contracts/collect/PartialCarbonRetirementCollectModule.sol'; +import {TokenGatedReferenceModule} from '../contracts/reference/TokenGatedReferenceModule.sol'; +import {ForkManagement} from '../script/helpers/ForkManagement.sol'; + +contract DeployBase is Script, ForkManagement { + using stdJson for string; + + uint256 deployerPrivateKey; + address deployer; + address lensHubProxy; + address moduleGlobals; + + function loadBaseAddresses(string memory json, string memory targetEnv) internal virtual { + lensHubProxy = json.readAddress(string(abi.encodePacked('.', targetEnv, '.LensHubProxy'))); + moduleGlobals = json.readAddress( + string(abi.encodePacked('.', targetEnv, '.ModuleGlobals')) + ); + } + + function loadPrivateKeys() internal { + string memory mnemonic = vm.envString('MNEMONIC'); + + if (bytes(mnemonic).length > 0) { + (deployer, deployerPrivateKey) = deriveRememberKey(mnemonic, 0); + } else { + deployerPrivateKey = vm.envUint('PRIVATE_KEY'); + deployer = vm.addr(deployerPrivateKey); + } + + console.log('\nDeployer address:', deployer); + console.log('Deployer balance:', deployer.balance); + } + + function run(string calldata targetEnv) external { + string memory json = loadJson(); + checkNetworkParams(json, targetEnv); + loadBaseAddresses(json, targetEnv); + loadPrivateKeys(); + + address module = deploy(); + console.log('New Deployment Address:', address(module)); + } + + function deploy() internal virtual returns (address) {} +} + +contract DeployStepwiseCollectModule is DeployBase { + function deploy() internal override returns (address) { + console.log('\nContract: StepwiseCollectModule'); + console.log('Init params:'); + console.log('\tLensHubProxy:', lensHubProxy); + console.log('\tModuleGlobals:', moduleGlobals); + + vm.startBroadcast(deployerPrivateKey); + StepwiseCollectModule stepwiseCollectModule = new StepwiseCollectModule( + lensHubProxy, + moduleGlobals + ); + vm.stopBroadcast(); + + console.log('Constructor arguments:'); + console.logBytes(abi.encode(lensHubProxy, moduleGlobals)); + + return address(stepwiseCollectModule); + } +} + +contract DeployMultirecipientFeeCollectModule is DeployBase { + function deploy() internal override returns (address) { + console.log('\nContract: MultirecipientFeeCollectModule'); + console.log('Init params:'); + console.log('\tLensHubProxy:', lensHubProxy); + console.log('\tModuleGlobals:', moduleGlobals); + + vm.startBroadcast(deployerPrivateKey); + MultirecipientFeeCollectModule module = new MultirecipientFeeCollectModule( + lensHubProxy, + moduleGlobals + ); + vm.stopBroadcast(); + + console.log('Constructor arguments:'); + console.logBytes(abi.encode(lensHubProxy, moduleGlobals)); + + return address(module); + } +} + +import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol'; + +contract DeployAaveFeeCollectModule is DeployBase { + using stdJson for string; + address poolAddressesProvider; + + function loadBaseAddresses(string memory json, string memory targetEnv) internal override { + super.loadBaseAddresses(json, targetEnv); + poolAddressesProvider = json.readAddress( + string(abi.encodePacked('.', targetEnv, '.PoolAddressesProvider')) + ); + } + + function deploy() internal override returns (address) { + console.log('\nContract: AaveFeeCollectModule'); + console.log('Init params:'); + console.log('\tLensHubProxy:', lensHubProxy); + console.log('\tModuleGlobals:', moduleGlobals); + console.log('\tPoolAddressesProvider:', poolAddressesProvider); + + vm.startBroadcast(deployerPrivateKey); + AaveFeeCollectModule module = new AaveFeeCollectModule( + lensHubProxy, + moduleGlobals, + IPoolAddressesProvider(poolAddressesProvider) + ); + vm.stopBroadcast(); + + console.log('Constructor arguments:'); + console.logBytes( + abi.encode(lensHubProxy, moduleGlobals, IPoolAddressesProvider(poolAddressesProvider)) + ); + + return address(module); + } +} + +contract DeployPartialCarbonRetirementCollectModule is DeployBase { + using stdJson for string; + + address retirementHelper = 0x802fd78B14bF8d0cc0Ba0325351887a323432B70; // Klima RetirementAggregatorV1 mainnet + + function deploy() internal override returns (address) { + console.log('\nContract: PartialCarbonRetirementCollectModule'); + console.log('Init params:'); + console.log('\tLensHubProxy:', lensHubProxy); + console.log('\tModuleGlobals:', moduleGlobals); + console.log('\tRetirementHelper:', retirementHelper); + + vm.startBroadcast(deployerPrivateKey); + PartialCarbonRetirementCollectModule module = new PartialCarbonRetirementCollectModule( + lensHubProxy, + moduleGlobals, + retirementHelper + ); + vm.stopBroadcast(); + + console.log('Constructor arguments:'); + console.logBytes( + abi.encode(lensHubProxy, moduleGlobals, retirementHelper) + ); + + return address(module); + } +} + +contract DeployPartialCarbonRetirementCollectModule is DeployBase { + using stdJson for string; + + address retirementHelper = 0x8cE54d9625371fb2a068986d32C85De8E6e995f8; // Klima KlimaInfinity/RetirementAggregatorV2 mainnet + function deploy() internal override returns (address) { + console.log('\nContract: PartialCarbonRetirementCollectModule'); + console.log('Init params:'); + console.log('\tLensHubProxy:', lensHubProxy); + console.log('\tModuleGlobals:', moduleGlobals); + console.log('\tRetirementHelper:', retirementHelper); + + vm.startBroadcast(deployerPrivateKey); + PartialCarbonRetirementCollectModule module = new PartialCarbonRetirementCollectModule( + lensHubProxy, + moduleGlobals, + retirementHelper + ); + vm.stopBroadcast(); + + console.log('Constructor arguments:'); + console.logBytes( + abi.encode(lensHubProxy, moduleGlobals, retirementHelper) + ); + + return address(module); + } +} + +contract DeployERC4626FeeCollectModule is DeployBase { + function deploy() internal override returns (address) { + console.log('\nContract: ERC4626FeeCollectModule'); + console.log('Init params:'); + console.log('\tLensHubProxy:', lensHubProxy); + console.log('\tModuleGlobals:', moduleGlobals); + + vm.startBroadcast(deployerPrivateKey); + ERC4626FeeCollectModule module = new ERC4626FeeCollectModule(lensHubProxy, moduleGlobals); + vm.stopBroadcast(); + + console.log('Constructor arguments:'); + console.logBytes(abi.encode(lensHubProxy, moduleGlobals)); + + return address(module); + } +} + +contract DeployTokenGatedReferenceModule is DeployBase { + function deploy() internal override returns (address) { + console.log('\nContract: TokenGatedReferenceModule'); + console.log('Init params:'); + console.log('\tLensHubProxy:', lensHubProxy); + + vm.startBroadcast(deployerPrivateKey); + TokenGatedReferenceModule module = new TokenGatedReferenceModule(lensHubProxy); + vm.stopBroadcast(); + + console.log('Constructor arguments:'); + console.logBytes(abi.encode(lensHubProxy)); + + return address(module); + } +} diff --git a/lens-protocol/modules/script/deploy-module.sh b/lens-protocol/modules/script/deploy-module.sh new file mode 100644 index 0000000..6fc2c58 --- /dev/null +++ b/lens-protocol/modules/script/deploy-module.sh @@ -0,0 +1,116 @@ +source .env + +set -e + +if [[ $1 == "" || $2 == "" || ($3 != "--verify-only" && $3 != "")]] + then + echo "Usage:" + echo " deploy-module.sh [target environment] [contractName] --verify-only [constructor-args]" + echo " where target environment (required): mainnet / testnet / sandbox" + echo " where contractName (required): contract name you want to deploy" + echo " --verify-only: if you only want to verify the existing deployment source code" + echo " [constructor-args] are ABI-Encoded for verification (see 'cast abi-encode' docs)" + echo "" + echo "Example:" + echo " deploy-module.sh sandbox StepwiseCollectModule" + exit 1 +fi + +if [[ $1 == "mainnet" ]] + then + VERIFIER_URL=$MAINNET_EXPLORER_API + else + if [[ $1 == "testnet" || $1 == "sandbox" ]] + then + VERIFIER_URL=$TESTNET_EXPLORER_API + else + echo "Unrecognized target environment '$1'. Should be one of mainnet/testnet/sandbox" + exit 1 + fi +fi + +NETWORK=$(node script/helpers/readNetwork.js $1) +if [[ $NETWORK == "" ]] + then + echo "No network found for $1 environment target in addresses.json. Terminating" + exit 1 +fi + +SAVED_ADDRESS=$(node script/helpers/readAddress.js $1 $2) +if [[ $3 == "--verify-only" ]] + then + echo "Running in verify-only mode (will verify the source code of existing deployment)" + if [[ $SAVED_ADDRESS != "" ]] + then + echo "Found $2 on '$1' at: $SAVED_ADDRESS" + read -p "Should we proceed with verification? (y/n):" CONFIRMATION + if [[ $CONFIRMATION != "y" && $CONFIRMATION != "Y" ]] + then + echo "Verification cancelled. Execution terminated." + exit 1 + fi + echo "forge verify-contract $SAVED_ADDRESS $2 --etherscan-api-key "$BLOCK_EXPLORER_KEY" --verifier-url "$VERIFIER_URL" --constructor-args "$4" --watch" + forge verify-contract $SAVED_ADDRESS $2 --etherscan-api-key "$BLOCK_EXPLORER_KEY" --verifier-url "$VERIFIER_URL" --constructor-args "$4" --watch + exit 0 + else + echo "Can't find the $2 deployment address on '$1' for verification. Terminating" + exit 1 + fi +fi + +if [[ $SAVED_ADDRESS != "" ]] + then + echo "Found $2 already deployed on $1 at: $SAVED_ADDRESS" + read -p "Should we redeploy it? (y/n):" CONFIRMATION + if [[ $CONFIRMATION != "y" && $CONFIRMATION != "Y" ]] + then + echo "Deployment cancelled. Execution terminated." + exit 1 + fi +fi + +CALLDATA=$(cast calldata "run(string)" $1) + +forge script script/deploy-module.s.sol:Deploy$2 -s $CALLDATA --rpc-url $NETWORK + +read -p "Please verify the data and confirm the deployment (y/n):" CONFIRMATION + +if [[ $CONFIRMATION == "y" || $CONFIRMATION == "Y" ]] + then + echo "Deploying..." + + echo $CALLDATA + echo $2 + echo $NETWORK + echo $MUMBAI_RPC_URL + #FORGE_OUTPUT=$(forge script script/deploy-module.s.sol:Deploy$2 -s $CALLDATA --rpc-url $NETWORK --broadcast) + # with gas estimate multiplier: 130 is default value according to foundry docs + FORGE_OUTPUT=$(forge script script/deploy-module.s.sol:Deploy$2 -s $CALLDATA --gas-estimate-multiplier 130 --rpc-url $NETWORK --broadcast) + #FORGE_OUTPUT=$(forge script script/deploy-module.s.sol:Deploy$2 -s $CALLDATA --rpc-url $MUMBAI_RPC_URL --broadcast) + echo "$FORGE_OUTPUT" + + DEPLOYED_ADDRESS=$(echo "$FORGE_OUTPUT" | grep "Contract Address:" | sed -n 's/.*: \(0x[0-9a-hA-H]\{40\}\)/\1/p') + + if [[ $DEPLOYED_ADDRESS == "" ]] + then + echo "Cannot find Deployed address of $2 in foundry logs. Terminating" + exit 1 + fi + + node script/helpers/saveAddress.js $1 $2 $DEPLOYED_ADDRESS + + CONSTRUCTOR_ARGS=$(echo "$FORGE_OUTPUT" | awk '/Constructor arguments:/{getline; gsub(/ /,""); print}') + echo "($CONSTRUCTOR_ARGS)" + + echo "" + read -p "Proceed with verification? (y/n):" CONFIRMATION + if [[ $CONFIRMATION == "y" || $CONFIRMATION == "Y" ]] + then + forge verify-contract $DEPLOYED_ADDRESS $2 --etherscan-api-key "$BLOCK_EXPLORER_KEY" --verifier-url "$VERIFIER_URL" --constructor-args "$CONSTRUCTOR_ARGS" --watch + else + "Verification cancelled. Terminating" + exit 1 + fi + else + echo "Deployment cancelled. Execution terminated." +fi diff --git a/lens-protocol/modules/script/helpers/ForkManagement.sol b/lens-protocol/modules/script/helpers/ForkManagement.sol new file mode 100644 index 0000000..431c2e3 --- /dev/null +++ b/lens-protocol/modules/script/helpers/ForkManagement.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import 'forge-std/Script.sol'; + +contract ForkManagement is Script { + using stdJson for string; + + function loadJson() internal returns (string memory) { + string memory root = vm.projectRoot(); + string memory path = string(abi.encodePacked(root, '/addresses.json')); + string memory json = vm.readFile(path); + return json; + } + + function checkNetworkParams(string memory json, string memory targetEnv) + internal + returns (string memory network, uint256 chainId) + { + network = json.readString(string(abi.encodePacked('.', targetEnv, '.network'))); + chainId = json.readUint(string(abi.encodePacked('.', targetEnv, '.chainId'))); + + console.log('\nTarget environment:', targetEnv); + console.log('Network:', network); + if (block.chainid != chainId) revert('Wrong chainId'); + console.log('ChainId:', chainId); + } + + function getNetwork(string memory json, string memory targetEnv) + internal + returns (string memory) + { + return json.readString(string(abi.encodePacked('.', targetEnv, '.network'))); + } +} diff --git a/lens-protocol/modules/script/helpers/readAddress.js b/lens-protocol/modules/script/helpers/readAddress.js new file mode 100644 index 0000000..8c86e99 --- /dev/null +++ b/lens-protocol/modules/script/helpers/readAddress.js @@ -0,0 +1,15 @@ +const path = require('path'); + +const addressesPath = '../../addresses.json'; + +const addresses = require(path.join(__dirname, addressesPath)); +const [targetEnv, contract] = process.argv.slice(2); + +if (!addresses[targetEnv]) { + console.error(`ERROR: Target environment "${targetEnv}" not found in addresses.json`); + process.exit(1); +} + +const address = addresses[targetEnv][contract]; + +console.log(address ?? ''); diff --git a/lens-protocol/modules/script/helpers/readNetwork.js b/lens-protocol/modules/script/helpers/readNetwork.js new file mode 100644 index 0000000..03ab5ea --- /dev/null +++ b/lens-protocol/modules/script/helpers/readNetwork.js @@ -0,0 +1,22 @@ +const path = require('path'); + +const addressesPath = '../../addresses.json'; + +const addresses = require(path.join(__dirname, addressesPath)); +const [targetEnv] = process.argv.slice(2); + +if (!addresses[targetEnv]) { + console.error(`ERROR: Target environment "${targetEnv}" not found in addresses.json`); + process.exit(1); +} + +const network = addresses[targetEnv].network; + +if (!network) { + console.error( + `ERROR: "network" parameter not found under "${targetEnv}" target environment in addresses.json` + ); + process.exit(1); +} + +console.log(network); diff --git a/lens-protocol/modules/script/helpers/saveAddress.js b/lens-protocol/modules/script/helpers/saveAddress.js new file mode 100644 index 0000000..708b8ba --- /dev/null +++ b/lens-protocol/modules/script/helpers/saveAddress.js @@ -0,0 +1,11 @@ +const path = require('path'); +const fs = require('fs'); + +const addressesPath = '../../addresses.json'; + +const addresses = require(path.join(__dirname, addressesPath)); +const [targetEnv, contract, address] = process.argv.slice(2); +addresses[targetEnv][contract] = address; + +fs.writeFileSync(path.join(__dirname, addressesPath), JSON.stringify(addresses, null, 2) + '\n'); +console.log('Updated `addresses.json`'); diff --git a/lens-protocol/modules/tasks/deployments/collect/deploy-ERC4626-fee-collect-module.ts b/lens-protocol/modules/tasks/deployments/collect/deploy-ERC4626-fee-collect-module.ts new file mode 100644 index 0000000..056f50e --- /dev/null +++ b/lens-protocol/modules/tasks/deployments/collect/deploy-ERC4626-fee-collect-module.ts @@ -0,0 +1,36 @@ +import '@nomiclabs/hardhat-ethers'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { deployWithVerify } from '../../helpers/utils'; +import { ERC4626FeeCollectModule__factory, LensHub__factory } from '../../../typechain'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +task( + 'deploy-ERC4626-fee-collect-module', + 'Deploys, verifies and whitelists the ERC4626 fee collect module' +) + .addParam('hub') + .addParam('globals') + .setAction(async ({ hub, globals }, hre) => { + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + + console.log('\n\n- - - - - - - - Deploying ERC4626 fee collect module\n\n'); + const erc4626FeeCollectModule = await deployWithVerify( + new ERC4626FeeCollectModule__factory(deployer).deploy(hub, globals), + [hub, globals], + 'contracts/collect/ERC4626FeeCollectModule.sol:ERC4626FeeCollectModule' + ); + + if (process.env.HARDHAT_NETWORK !== 'matic') { + console.log('\n\n- - - - - - - - Whitelisting ERC4626 fee collect module\n\n'); + await LensHub__factory.connect(hub, governance).whitelistCollectModule( + erc4626FeeCollectModule.address, + true + ); + } + }); diff --git a/lens-protocol/modules/tasks/deployments/collect/deploy-aave-fee-collect-module.ts b/lens-protocol/modules/tasks/deployments/collect/deploy-aave-fee-collect-module.ts new file mode 100644 index 0000000..4a1864c --- /dev/null +++ b/lens-protocol/modules/tasks/deployments/collect/deploy-aave-fee-collect-module.ts @@ -0,0 +1,47 @@ +import '@nomiclabs/hardhat-ethers'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { deployWithVerify } from '../../helpers/utils'; +import { AaveFeeCollectModule__factory, LensHub__factory } from '../../../typechain'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +const POOL_ADDRESSES_PROVIDER_ADDRESS_MUMBAI = '0x5343b5bA672Ae99d627A1C87866b8E53F47Db2E6'; +const POOL_ADDRESSES_PROVIDER_ADDRESS_POLYGON = '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb'; + +task( + 'deploy-aave-fee-collect-module', + 'Deploys, verifies and whitelists the Aave fee collect module' +) + .addParam('hub') + .addParam('globals') + .addOptionalParam('poolAddressProvider') + .setAction(async ({ hub, globals, poolAddressProvider }, hre) => { + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + + // Setting pool address provider if left undefined + if (!poolAddressProvider) + poolAddressProvider = + process.env.HARDHAT_NETWORK == 'matic' + ? POOL_ADDRESSES_PROVIDER_ADDRESS_POLYGON + : POOL_ADDRESSES_PROVIDER_ADDRESS_MUMBAI; + + console.log('\n\n- - - - - - - - Deploying Aave fee collect module\n\n'); + const aaveFeeCollectModule = await deployWithVerify( + new AaveFeeCollectModule__factory(deployer).deploy(hub, globals, poolAddressProvider), + [hub, globals, poolAddressProvider], + 'contracts/collect/AaveFeeCollectModule.sol:AaveFeeCollectModule' + ); + + if (process.env.HARDHAT_NETWORK !== 'matic') { + console.log('\n\n- - - - - - - - Whitelisting Aave fee collect module\n\n'); + await LensHub__factory.connect(hub, governance).whitelistCollectModule( + aaveFeeCollectModule.address, + true + ); + } + }); diff --git a/lens-protocol/modules/tasks/deployments/collect/deploy-auction-collect-module.ts b/lens-protocol/modules/tasks/deployments/collect/deploy-auction-collect-module.ts new file mode 100644 index 0000000..4f4a8aa --- /dev/null +++ b/lens-protocol/modules/tasks/deployments/collect/deploy-auction-collect-module.ts @@ -0,0 +1,31 @@ +import '@nomiclabs/hardhat-ethers'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { deployWithVerify } from '../../helpers/utils'; +import { AuctionCollectModule__factory, LensHub__factory } from '../../../typechain'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +task('deploy-auction-collect-module', 'Deploys, verifies and whitelists the auction collect module') + .addParam('hub') + .addParam('globals') + .setAction(async ({ hub, globals }, hre) => { + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + + console.log('\n\n- - - - - - - - Deploying auction collect module\n\n'); + const auctionCollectModule = await deployWithVerify( + new AuctionCollectModule__factory(deployer).deploy(hub, globals), + [hub, globals], + 'contracts/collect/AuctionCollectModule.sol:AuctionCollectModule' + ); + + console.log('\n\n- - - - - - - - Whitelisting auction collect module\n\n'); + await LensHub__factory.connect(hub, governance).whitelistCollectModule( + auctionCollectModule.address, + true + ); + }); diff --git a/lens-protocol/modules/tasks/deployments/collect/deploy-partial-carbon-retirement-collect-module.ts b/lens-protocol/modules/tasks/deployments/collect/deploy-partial-carbon-retirement-collect-module.ts new file mode 100644 index 0000000..d799f75 --- /dev/null +++ b/lens-protocol/modules/tasks/deployments/collect/deploy-partial-carbon-retirement-collect-module.ts @@ -0,0 +1,41 @@ +import '@nomiclabs/hardhat-ethers'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { deployWithVerify } from '../../helpers/utils'; +import { PartialCarbonRetirementCollectModule__factory, LensHub__factory } from '../../../typechain'; + +// External contract addresses +// Hard-coded for testnet, NOT SUITABLE FOR PRODUCTION! +// Alternative: inject values from an environment variable// Hard-coded for testnet, not suitable for production +const RETIREMENT_HELPER_ADDRESS = '0x802fd78B14bF8d0cc0Ba0325351887a323432B70'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +task( + 'deploy-partial-carbon-retirement-collect-module', + 'Deploys, verifies and whitelists the partial carbon retirement collect module' +) + .addParam('hub') + .addParam('globals') + .setAction(async ({ hub, globals }, hre) => { + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + + console.log('\n\n- - - - - - - - Deploying partial carbon retirement fee collect module\n\n'); + const partialCarbonRetirementCollectModule = await deployWithVerify( + new PartialCarbonRetirementCollectModule__factory(deployer).deploy(hub, globals, RETIREMENT_HELPER_ADDRESS), + [hub, globals], + 'contracts/collect/PartialCarbonRetirementCollectModule.sol:PartialCarbonRetirementCollectModule' + ); + + if (process.env.HARDHAT_NETWORK !== 'matic') { + console.log('\n\n- - - - - - - - Whitelisting partial carbon retirement fee collect module\n\n'); + await LensHub__factory.connect(hub, governance).whitelistCollectModule( + partialCarbonRetirementCollectModule.address, + true + ); + } + }); diff --git a/lens-protocol/modules/tasks/deployments/collect/deploy-stepwise-collect-module.ts b/lens-protocol/modules/tasks/deployments/collect/deploy-stepwise-collect-module.ts new file mode 100644 index 0000000..7edb5e1 --- /dev/null +++ b/lens-protocol/modules/tasks/deployments/collect/deploy-stepwise-collect-module.ts @@ -0,0 +1,36 @@ +import '@nomiclabs/hardhat-ethers'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { deployWithVerify } from '../../helpers/utils'; +import { StepwiseCollectModule__factory, LensHub__factory } from '../../../typechain'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +task( + 'deploy-stepwise-collect-module', + 'Deploys, verifies and whitelists the stepwise collect module' +) + .addParam('hub') + .addParam('globals') + .setAction(async ({ hub, globals }, hre) => { + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + + console.log('\n\n- - - - - - - - Deploying stepwise fee collect module\n\n'); + const stepwiseCollectModule = await deployWithVerify( + new StepwiseCollectModule__factory(deployer).deploy(hub, globals), + [hub, globals], + 'contracts/collect/StepwiseCollectModule.sol:StepwiseCollectModule' + ); + + if (process.env.HARDHAT_NETWORK !== 'matic') { + console.log('\n\n- - - - - - - - Whitelisting stepwise fee collect module\n\n'); + await LensHub__factory.connect(hub, governance).whitelistCollectModule( + stepwiseCollectModule.address, + true + ); + } + }); diff --git a/lens-protocol/modules/tasks/deployments/collect/deploy-updatable-ownable-fee-collect-module.ts b/lens-protocol/modules/tasks/deployments/collect/deploy-updatable-ownable-fee-collect-module.ts new file mode 100644 index 0000000..6d487c5 --- /dev/null +++ b/lens-protocol/modules/tasks/deployments/collect/deploy-updatable-ownable-fee-collect-module.ts @@ -0,0 +1,34 @@ +import '@nomiclabs/hardhat-ethers'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { deployWithVerify } from '../../helpers/utils'; +import { UpdatableOwnableFeeCollectModule__factory, LensHub__factory } from '../../../typechain'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +task( + 'deploy-updatable-ownable-fee-collect-module', + 'Deploys, verifies and whitelists the updatable ownable fee collect module' +) + .addParam('hub') + .addParam('globals') + .setAction(async ({ hub, globals }, hre) => { + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + + console.log('\n\n- - - - - - - - Deploying updatable ownable fee collect module\n\n'); + const updatableOwnableFeeCollectModule = await deployWithVerify( + new UpdatableOwnableFeeCollectModule__factory(deployer).deploy(hub, globals), + [hub, globals], + 'contracts/collect/UpdatableOwnableFeeCollectModule.sol:UpdatableOwnableFeeCollectModule' + ); + + console.log('\n\n- - - - - - - - Whitelisting updatable ownable fee collect module\n\n'); + await LensHub__factory.connect(hub, governance).whitelistCollectModule( + updatableOwnableFeeCollectModule.address, + true + ); + }); diff --git a/lens-protocol/modules/tasks/deployments/reference/deploy-degrees-of-separation-reference-module.ts b/lens-protocol/modules/tasks/deployments/reference/deploy-degrees-of-separation-reference-module.ts new file mode 100644 index 0000000..c19519a --- /dev/null +++ b/lens-protocol/modules/tasks/deployments/reference/deploy-degrees-of-separation-reference-module.ts @@ -0,0 +1,33 @@ +import '@nomiclabs/hardhat-ethers'; +import { task } from 'hardhat/config'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { deployWithVerify } from '../../helpers/utils'; +import { DegreesOfSeparationReferenceModule__factory, LensHub__factory } from '../../../typechain'; + +export let runtimeHRE: HardhatRuntimeEnvironment; + +task( + 'deploy-degrees-of-separation-reference-module', + 'Deploys, verifies and whitelists the degrees of separation reference module' +) + .addParam('hub') + .setAction(async ({ hub }, hre) => { + runtimeHRE = hre; + const ethers = hre.ethers; + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + const governance = accounts[1]; + + console.log('\n\n- - - - - - - - Deploying degrees of separation reference module\n\n'); + const degreesOfSeparationReferenceModule = await deployWithVerify( + new DegreesOfSeparationReferenceModule__factory(deployer).deploy(hub), + [hub], + 'contracts/reference/DegreesOfSeparationReferenceModule.sol:DegreesOfSeparationReferenceModule' + ); + + console.log('\n\n- - - - - - - - Whitelisting degrees of separation reference module\n\n'); + await LensHub__factory.connect(hub, governance).whitelistReferenceModule( + degreesOfSeparationReferenceModule.address, + true + ); + }); diff --git a/lens-protocol/modules/tasks/helpers/utils.ts b/lens-protocol/modules/tasks/helpers/utils.ts new file mode 100644 index 0000000..e423fef --- /dev/null +++ b/lens-protocol/modules/tasks/helpers/utils.ts @@ -0,0 +1,83 @@ +import '@nomiclabs/hardhat-ethers'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { Contract, ContractTransaction } from 'ethers'; +import fs from 'fs'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; + +export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + +export enum ProtocolState { + Unpaused, + PublishingPaused, + Paused, +} + +export function getAddrs(): any { + const json = fs.readFileSync('addresses.json', 'utf8'); + const addrs = JSON.parse(json); + return addrs; +} + +export async function waitForTx(tx: Promise) { + await (await tx).wait(); +} + +export async function deployContract(tx: any): Promise { + const result = await tx; + await result.deployTransaction.wait(); + return result; +} + +export async function deployWithVerify( + tx: any, + args: any, + contractPath: string +): Promise { + const deployedContract = await deployContract(tx); + let count = 0; + let maxTries = 8; + const runtimeHRE = require('hardhat'); + while (true) { + await delay(10000); + try { + console.log('Verifying contract at', deployedContract.address); + await runtimeHRE.run('verify:verify', { + address: deployedContract.address, + constructorArguments: args, + contract: contractPath, + }); + break; + } catch (error) { + if (String(error).includes('Already Verified')) { + console.log( + `Already verified contract at ${contractPath} at address ${deployedContract.address}` + ); + break; + } + if (++count == maxTries) { + console.log( + `Failed to verify contract at ${contractPath} at address ${deployedContract.address}, error: ${error}` + ); + break; + } + console.log(`Retrying... Retry #${count}, last error: ${error}`); + } + } + + return deployedContract; +} + +export async function initEnv(hre: HardhatRuntimeEnvironment): Promise { + const ethers = hre.ethers; // This allows us to access the hre (Hardhat runtime environment)'s injected ethers instance easily + + const accounts = await ethers.getSigners(); // This returns an array of the default signers connected to the hre's ethers instance + const governance = accounts[1]; + const treasury = accounts[2]; + const user = accounts[3]; + + return [governance, treasury, user]; +} + +async function delay(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/lens-protocol/modules/test/__setup.spec.ts b/lens-protocol/modules/test/__setup.spec.ts new file mode 100644 index 0000000..343fb97 --- /dev/null +++ b/lens-protocol/modules/test/__setup.spec.ts @@ -0,0 +1,330 @@ +import { AbiCoder } from '@ethersproject/abi'; +import { parseEther } from '@ethersproject/units'; +import '@nomiclabs/hardhat-ethers'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { expect, use } from 'chai'; +import { solidity } from 'ethereum-waffle'; +import { BytesLike, Wallet } from 'ethers'; +import { ethers } from 'hardhat'; +import { + CollectNFT__factory, + Events, + Events__factory, + FollowNFT__factory, + InteractionLogic__factory, + LensHub, + LensHub__factory, + ProfileTokenURILogic__factory, + PublishingLogic__factory, + FollowNFT, + CollectNFT, + ModuleGlobals__factory, + TransparentUpgradeableProxy__factory, + Currency__factory, + Currency, + ACurrency, + ACurrency__factory, + NFT__factory, + NFT, + ModuleGlobals, + AuctionCollectModule, + AuctionCollectModule__factory, + FreeCollectModule__factory, + FreeCollectModule, + MockPool, + MockPool__factory, + MockPoolAddressesProvider, + MockPoolAddressesProvider__factory, + AaveFeeCollectModule, + AaveFeeCollectModule__factory, + UpdatableOwnableFeeCollectModule, + UpdatableOwnableFeeCollectModule__factory, + MockVault, + MockVault__factory, + ERC4626FeeCollectModule, + ERC4626FeeCollectModule__factory, + TokenGatedReferenceModule__factory, + TokenGatedReferenceModule, + DegreesOfSeparationReferenceModule, + DegreesOfSeparationReferenceModule__factory, + StepwiseCollectModule, + StepwiseCollectModule__factory, + PartialCarbonRetirementCollectModule, + PartialCarbonRetirementCollectModule__factory, + MockKlimaRetirementAggregator, + MockKlimaRetirementAggregator__factory, +} from '../typechain'; +import { LensHubLibraryAddresses } from '../typechain/factories/LensHub__factory'; +import { ProfileFollowModule__factory } from '../typechain/factories/ProfileFollowModule__factory'; +import { ProfileFollowModule } from '../typechain/ProfileFollowModule'; +import { + computeContractAddress, + ProtocolState, + revertToSnapshot, + takeSnapshot, +} from './helpers/utils'; + +use(solidity); + +export const CURRENCY_MINT_AMOUNT = parseEther('100'); +export const BPS_MAX = 10000; +export const TREASURY_FEE_BPS = 50; +export const REFERRAL_FEE_BPS = 250; +export const MAX_PROFILE_IMAGE_URI_LENGTH = 6000; +export const LENS_HUB_NFT_NAME = 'Lens Protocol Profiles'; +export const LENS_HUB_NFT_SYMBOL = 'LPP'; +export const MOCK_PROFILE_HANDLE = 'satoshi.lens'; +export const FIRST_PROFILE_ID = 1; +export const FIRST_PUB_ID = 1; +export const FIRST_FOLLOW_NFT_ID = 1; +export const MOCK_URI = 'https://ipfs.io/ipfs/QmY9dUwYu67puaWBMxRKW98LPbXCznPwHUbhX5NeWnCJbX'; +export const OTHER_MOCK_URI = 'https://ipfs.io/ipfs/QmTFLSXdEQ6qsSzaXaCSNtiv6wA56qq87ytXJ182dXDQJS'; +export const MOCK_PROFILE_URI = + 'https://ipfs.io/ipfs/Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu'; +export const MOCK_FOLLOW_NFT_URI = + 'https://ipfs.io/ipfs/QmU8Lv1fk31xYdghzFrLm6CiFcwVg7hdgV6BBWesu6EqLj'; +export const DEFAULT_AMOUNT = parseEther('2'); + +export let chainId: number; +export let accounts: SignerWithAddress[]; +export let deployer: SignerWithAddress; +export let governance: SignerWithAddress; +export let proxyAdmin: SignerWithAddress; +export let treasury: SignerWithAddress; +export let user: SignerWithAddress; +export let anotherUser: SignerWithAddress; +export let thirdUser: SignerWithAddress; +export let publisher: SignerWithAddress; +export let feeRecipient: SignerWithAddress; +export let collector: SignerWithAddress; + +export let lensHubImpl: LensHub; +export let lensHub: LensHub; +export let currency: Currency; +export let aCurrency: ACurrency; +export let currencyTwo: Currency; +export let aavePool: MockPool; +export let aavePoolAddressesProvider: MockPoolAddressesProvider; +export let nft: NFT; +export let abiCoder: AbiCoder; +export let mockModuleData: BytesLike; +export let hubLibs: LensHubLibraryAddresses; +export let eventsLib: Events; +export let moduleGlobals: ModuleGlobals; +export let followNFTImpl: FollowNFT; +export let collectNFTImpl: CollectNFT; +export let freeCollectModule: FreeCollectModule; +export let mockVault: MockVault; +export let mockVaultTwo: MockVault; +export let profileFollowModule: ProfileFollowModule; + +export let auctionCollectModule: AuctionCollectModule; +export let aaveFeeCollectModule: AaveFeeCollectModule; +export let updatableOwnableFeeCollectModule: UpdatableOwnableFeeCollectModule; +export let stepwiseCollectModule: StepwiseCollectModule; +export let erc4626FeeCollectModule: ERC4626FeeCollectModule; +export let partialCarbonRetirementCollectModule: PartialCarbonRetirementCollectModule; + +export let degreesOfSeparationReferenceModule: DegreesOfSeparationReferenceModule; + +export let tokenGatedReferenceModule: TokenGatedReferenceModule; + +//helpers (from addBCTRetirement...Module) +export let carbonToken: Currency; +export let mockKlimaRetirementAggregator: MockKlimaRetirementAggregator; + +export function makeSuiteCleanRoom(name: string, tests: () => void) { + describe(name, () => { + beforeEach(async function () { + await takeSnapshot(); + }); + tests(); + afterEach(async function () { + await revertToSnapshot(); + }); + }); +} + +beforeEach(async function () { + chainId = (await ethers.provider.getNetwork()).chainId; + abiCoder = ethers.utils.defaultAbiCoder; + accounts = await ethers.getSigners(); + deployer = accounts[0]; + governance = accounts[1]; + proxyAdmin = accounts[2]; + treasury = accounts[3]; + user = accounts[4]; + anotherUser = accounts[5]; + thirdUser = accounts[6]; + publisher = accounts[7]; + feeRecipient = accounts[8]; + + // Deployment + moduleGlobals = await new ModuleGlobals__factory(deployer).deploy( + governance.address, + treasury.address, + TREASURY_FEE_BPS + ); + const publishingLogic = await new PublishingLogic__factory(deployer).deploy(); + const interactionLogic = await new InteractionLogic__factory(deployer).deploy(); + const profileTokenURILogic = await new ProfileTokenURILogic__factory(deployer).deploy(); + hubLibs = { + '@aave/lens-protocol/contracts/libraries/PublishingLogic.sol:PublishingLogic': + publishingLogic.address, + '@aave/lens-protocol/contracts/libraries/InteractionLogic.sol:InteractionLogic': + interactionLogic.address, + '@aave/lens-protocol/contracts/libraries/ProfileTokenURILogic.sol:ProfileTokenURILogic': + profileTokenURILogic.address, + }; + + // Here, we pre-compute the nonces and addresses used to deploy the contracts. + const nonce = await deployer.getTransactionCount(); + // nonce + 0 is follow NFT impl + // nonce + 1 is collect NFT impl + // nonce + 2 is impl + // nonce + 3 is hub proxy + + const hubProxyAddress = computeContractAddress(deployer.address, nonce + 3); // '0x' + keccak256(RLP.encode([deployerAddress, hubProxyNonce])).substr(26); + + followNFTImpl = await new FollowNFT__factory(deployer).deploy(hubProxyAddress); + collectNFTImpl = await new CollectNFT__factory(deployer).deploy(hubProxyAddress); + + lensHubImpl = await new LensHub__factory(hubLibs, deployer).deploy( + followNFTImpl.address, + collectNFTImpl.address + ); + + const data = lensHubImpl.interface.encodeFunctionData('initialize', [ + LENS_HUB_NFT_NAME, + LENS_HUB_NFT_SYMBOL, + governance.address, + ]); + const proxy = await new TransparentUpgradeableProxy__factory(deployer).deploy( + lensHubImpl.address, + proxyAdmin.address, + data + ); + + // Connect the hub proxy to the LensHub factory and the user for ease of use. + lensHub = LensHub__factory.connect(proxy.address, deployer); + + // Currency + currency = await new Currency__factory(deployer).deploy(); + currencyTwo = await new Currency__factory(deployer).deploy(); + aCurrency = await new ACurrency__factory(deployer).deploy(); + + // ERC4626 Vault - accepts 'currency' as deposit asset + mockVault = await new MockVault__factory(deployer).deploy(currency.address); + mockVaultTwo = await new MockVault__factory(deployer).deploy(currencyTwo.address); + + // Aave Pool - currencyTwo is set as unsupported asset (in Aave, not Lens) for testing + aavePool = await new MockPool__factory(deployer).deploy(aCurrency.address, currencyTwo.address); + aavePoolAddressesProvider = await new MockPoolAddressesProvider__factory(deployer).deploy( + aavePool.address + ); + + // NFT + nft = await new NFT__factory(deployer).deploy(); + + // Currency whitelisting + await expect( + moduleGlobals.connect(governance).whitelistCurrency(currency.address, true) + ).to.not.be.reverted; + await expect( + moduleGlobals.connect(governance).whitelistCurrency(currencyTwo.address, true) + ).to.not.be.reverted; + + // Modules used for testing purposes + freeCollectModule = await new FreeCollectModule__factory(deployer).deploy(lensHub.address); + await expect( + lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true) + ).to.not.be.reverted; + profileFollowModule = await new ProfileFollowModule__factory(deployer).deploy(lensHub.address); + await expect( + lensHub.connect(governance).whitelistFollowModule(profileFollowModule.address, true) + ).to.not.be.reverted; + + // Collect modules + auctionCollectModule = await new AuctionCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ); + aaveFeeCollectModule = await new AaveFeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address, + aavePoolAddressesProvider.address + ); + + await expect( + lensHub.connect(governance).whitelistCollectModule(auctionCollectModule.address, true) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(aaveFeeCollectModule.address, true) + ).to.not.be.reverted; + + updatableOwnableFeeCollectModule = await new UpdatableOwnableFeeCollectModule__factory( + deployer + ).deploy(lensHub.address, moduleGlobals.address); + await expect( + lensHub + .connect(governance) + .whitelistCollectModule(updatableOwnableFeeCollectModule.address, true) + ).to.not.be.reverted; + + erc4626FeeCollectModule = await new ERC4626FeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ); + await expect( + lensHub.connect(governance).whitelistCollectModule(erc4626FeeCollectModule.address, true) + ).to.not.be.reverted; + + // Reference modules + degreesOfSeparationReferenceModule = await new DegreesOfSeparationReferenceModule__factory( + deployer + ).deploy(lensHub.address); + await expect( + lensHub + .connect(governance) + .whitelistReferenceModule(degreesOfSeparationReferenceModule.address, true) + ).to.not.be.reverted; + + // Reference modules + tokenGatedReferenceModule = await new TokenGatedReferenceModule__factory(deployer).deploy( + lensHub.address + ); + await expect( + lensHub.connect(governance).whitelistReferenceModule(tokenGatedReferenceModule.address, true) + ).to.not.be.reverted; + + // Collect modules + stepwiseCollectModule = await new StepwiseCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ); + await expect( + lensHub.connect(governance).whitelistCollectModule(stepwiseCollectModule.address, true) + ).to.not.be.reverted; + + // Carbon Offset Retirement Collect modules + //carbonToken = await new Currency__factory(deployer).deploy(); + mockKlimaRetirementAggregator = await new MockKlimaRetirementAggregator__factory(deployer).deploy(); + partialCarbonRetirementCollectModule = await new PartialCarbonRetirementCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address, + //carbonToken.address, + mockKlimaRetirementAggregator.address + ); + + // Unpausing protocol + await expect(lensHub.connect(governance).setState(ProtocolState.Unpaused)).to.not.be.reverted; + + // Profile creator whitelisting + await expect( + lensHub.connect(governance).whitelistProfileCreator(deployer.address, true) + ).to.not.be.reverted; + + // Event library deployment is only needed for testing and is not reproduced in the live environment + eventsLib = await new Events__factory(deployer).deploy(); +}); diff --git a/lens-protocol/modules/test/foundry/BaseSetup.t.sol b/lens-protocol/modules/test/foundry/BaseSetup.t.sol new file mode 100644 index 0000000..8608ed3 --- /dev/null +++ b/lens-protocol/modules/test/foundry/BaseSetup.t.sol @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import 'forge-std/Test.sol'; + +// Deployments +import {LensHub} from '@aave/lens-protocol/contracts/core/LensHub.sol'; +import {FollowNFT} from '@aave/lens-protocol/contracts/core/FollowNFT.sol'; +import {CollectNFT} from '@aave/lens-protocol/contracts/core/CollectNFT.sol'; +import {ModuleGlobals} from '@aave/lens-protocol/contracts/core/modules/ModuleGlobals.sol'; +import {FreeCollectModule} from '@aave/lens-protocol/contracts/core/modules/collect/FreeCollectModule.sol'; +import {TransparentUpgradeableProxy} from '@aave/lens-protocol/contracts/upgradeability/TransparentUpgradeableProxy.sol'; +import {DataTypes} from '@aave/lens-protocol/contracts/libraries/DataTypes.sol'; +import {Errors} from '@aave/lens-protocol/contracts/libraries/Errors.sol'; +import {ForkManagement} from 'script/helpers/ForkManagement.sol'; + +import {Currency} from '@aave/lens-protocol/contracts/mocks/Currency.sol'; +import {NFT} from 'contracts/mocks/NFT.sol'; + +contract BaseSetup is Test, ForkManagement { + using stdJson for string; + + string forkEnv; + bool fork; + string network; + string json; + uint256 forkBlockNumber; + + uint256 firstProfileId; + address deployer; + address governance; + address treasury; + + address constant publisher = address(4); + address constant user = address(5); + address constant userTwo = address(6); + address constant userThree = address(7); + address constant userFour = address(8); + address constant userFive = address(9); + address immutable me = address(this); + + string constant MOCK_HANDLE = 'mock'; + string constant MOCK_URI = 'ipfs://QmUXfQWe43RKx31VzA2BnbwhSMW8WuaJvszFWChD59m76U'; + string constant OTHER_MOCK_URI = + 'https://ipfs.io/ipfs/QmTFLSXdEQ6qsSzaXaCSNtiv6wA56qq87ytXJ182dXDQJS'; + string constant MOCK_FOLLOW_NFT_URI = + 'https://ipfs.io/ipfs/QmU8Lv1fk31xYdghzFrLm6CiFcwVg7hdgV6BBWesu6EqLj'; + + uint16 TREASURY_FEE_BPS; + uint16 constant TREASURY_FEE_MAX_BPS = 10000; + + address hubProxyAddr; + CollectNFT collectNFT; + FollowNFT followNFT; + LensHub hubImpl; + TransparentUpgradeableProxy hubAsProxy; + LensHub hub; + FreeCollectModule freeCollectModule; + Currency currency; + ModuleGlobals moduleGlobals; + NFT nft; + + // TODO: Replace with forge-std/StdJson.sol::keyExists(...) when/if this PR is approved: + // https://github.com/foundry-rs/forge-std/pull/226 + function keyExists(string memory key) internal returns (bool) { + return json.parseRaw(key).length > 0; + } + + function loadBaseAddresses(string memory json, string memory targetEnv) internal virtual { + bytes32 PROXY_IMPLEMENTATION_STORAGE_SLOT = bytes32( + uint256(keccak256('eip1967.proxy.implementation')) - 1 + ); + + console.log('targetEnv:', targetEnv); + + hubProxyAddr = json.readAddress(string(abi.encodePacked('.', targetEnv, '.LensHubProxy'))); + console.log('hubProxyAddr:', hubProxyAddr); + + hub = LensHub(hubProxyAddr); + + console.log('Hub:', address(hub)); + + address followNFTAddr = hub.getFollowNFTImpl(); + address collectNFTAddr = hub.getCollectNFTImpl(); + + address hubImplAddr = address( + uint160(uint256(vm.load(hubProxyAddr, PROXY_IMPLEMENTATION_STORAGE_SLOT))) + ); + console.log('Found hubImplAddr:', hubImplAddr); + hubImpl = LensHub(hubImplAddr); + followNFT = FollowNFT(followNFTAddr); + collectNFT = CollectNFT(collectNFTAddr); + hubAsProxy = TransparentUpgradeableProxy(payable(address(hub))); + freeCollectModule = FreeCollectModule( + json.readAddress(string(abi.encodePacked('.', targetEnv, '.FreeCollectModule'))) + ); + + moduleGlobals = ModuleGlobals( + json.readAddress(string(abi.encodePacked('.', targetEnv, '.ModuleGlobals'))) + ); + + currency = new Currency(); + nft = new NFT(); + + firstProfileId = uint256(vm.load(hubProxyAddr, bytes32(uint256(22)))) + 1; + console.log('firstProfileId:', firstProfileId); + + deployer = address(1); + + governance = hub.getGovernance(); + treasury = moduleGlobals.getTreasury(); + + TREASURY_FEE_BPS = moduleGlobals.getTreasuryFee(); + } + + function deployBaseContracts() internal { + firstProfileId = 1; + deployer = address(1); + governance = address(2); + treasury = address(3); + + TREASURY_FEE_BPS = 50; + + ///////////////////////////////////////// Start deployments. + vm.startPrank(deployer); + + // Precompute needed addresss. + address followNFTAddr = computeCreateAddress(deployer, 1); + address collectNFTAddr = computeCreateAddress(deployer, 2); + hubProxyAddr = computeCreateAddress(deployer, 3); + + // Deploy implementation contracts. + hubImpl = new LensHub(followNFTAddr, collectNFTAddr); + followNFT = new FollowNFT(hubProxyAddr); + collectNFT = new CollectNFT(hubProxyAddr); + + // Deploy and initialize proxy. + bytes memory initData = abi.encodeWithSelector( + hubImpl.initialize.selector, + 'Lens Protocol Profiles', + 'LPP', + governance + ); + hubAsProxy = new TransparentUpgradeableProxy(address(hubImpl), deployer, initData); + + // Cast proxy to LensHub interface. + hub = LensHub(address(hubAsProxy)); + + // Deploy the FreeCollectModule. + freeCollectModule = new FreeCollectModule(hubProxyAddr); + + moduleGlobals = new ModuleGlobals(governance, treasury, TREASURY_FEE_BPS); + + currency = new Currency(); + nft = new NFT(); + + vm.stopPrank(); + ///////////////////////////////////////// End deployments. + } + + constructor() { + forkEnv = vm.envString('TESTING_FORK'); + + if (bytes(forkEnv).length > 0) { + fork = true; + console.log('\n\n Testing using %s fork', forkEnv); + json = loadJson(); + + network = getNetwork(json, forkEnv); + vm.createSelectFork(network); + + forkBlockNumber = block.number; + console.log('Fork Block number:', forkBlockNumber); + + checkNetworkParams(json, forkEnv); + + loadBaseAddresses(json, forkEnv); + } else { + deployBaseContracts(); + } + ///////////////////////////////////////// Start governance actions. + vm.startPrank(governance); + + if (hub.getState() != DataTypes.ProtocolState.Unpaused) + hub.setState(DataTypes.ProtocolState.Unpaused); + + // Whitelist the FreeCollectModule. + hub.whitelistCollectModule(address(freeCollectModule), true); + + // Whitelist the test contract as a profile creator + hub.whitelistProfileCreator(me, true); + + // Whitelist mock currency in ModuleGlobals + moduleGlobals.whitelistCurrency(address(currency), true); + + vm.stopPrank(); + ///////////////////////////////////////// End governance actions. + } + + function _toUint256Array(uint256 n) internal pure returns (uint256[] memory) { + uint256[] memory ret = new uint256[](1); + ret[0] = n; + return ret; + } + + function _toBytesArray(bytes memory n) internal pure returns (bytes[] memory) { + bytes[] memory ret = new bytes[](1); + ret[0] = n; + return ret; + } +} diff --git a/lens-protocol/modules/test/foundry/collect/BaseFeeCollectModule.base.sol b/lens-protocol/modules/test/foundry/collect/BaseFeeCollectModule.base.sol new file mode 100644 index 0000000..0079c09 --- /dev/null +++ b/lens-protocol/modules/test/foundry/collect/BaseFeeCollectModule.base.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import 'forge-std/Test.sol'; +import '../BaseSetup.t.sol'; +import {SimpleFeeCollectModule} from 'contracts/collect/SimpleFeeCollectModule.sol'; +import {BaseFeeCollectModuleInitData} from 'contracts/collect/base/IBaseFeeCollectModule.sol'; + +contract BaseFeeCollectModuleBase is BaseSetup { + address baseFeeCollectModule; + + BaseFeeCollectModuleInitData exampleInitData; + + uint256 constant DEFAULT_COLLECT_LIMIT = 3; + uint16 constant REFERRAL_FEE_BPS = 250; + + // Deploy & Whitelist BaseFeeCollectModule + constructor() BaseSetup() { + vm.prank(deployer); + baseFeeCollectModule = address( + new SimpleFeeCollectModule(hubProxyAddr, address(moduleGlobals)) + ); + vm.prank(governance); + hub.whitelistCollectModule(address(baseFeeCollectModule), true); + } + + function getEncodedInitData() internal virtual returns (bytes memory) { + return abi.encode(exampleInitData); + } +} diff --git a/lens-protocol/modules/test/foundry/collect/BaseFeeCollectModule.test.sol b/lens-protocol/modules/test/foundry/collect/BaseFeeCollectModule.test.sol new file mode 100644 index 0000000..26a76f9 --- /dev/null +++ b/lens-protocol/modules/test/foundry/collect/BaseFeeCollectModule.test.sol @@ -0,0 +1,865 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import '../BaseSetup.t.sol'; +import {BaseFeeCollectModuleBase} from './BaseFeeCollectModule.base.sol'; +import {IBaseFeeCollectModule, BaseProfilePublicationData, BaseFeeCollectModuleInitData} from 'contracts/collect/base/IBaseFeeCollectModule.sol'; +import {SimpleFeeCollectModule} from 'contracts/collect/SimpleFeeCollectModule.sol'; + +import '../helpers/TestHelpers.sol'; +import '@aave/lens-protocol/contracts/libraries/Events.sol'; + +uint16 constant BPS_MAX = 10000; + +///////// +// Publication Creation with BaseFeeCollectModule +// +contract BaseFeeCollectModule_Publication is BaseFeeCollectModuleBase { + uint256 immutable userProfileId; + + constructor() BaseFeeCollectModuleBase() { + userProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: me, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + } + + function setUp() public { + exampleInitData.amount = 1 ether; + exampleInitData.collectLimit = 0; + exampleInitData.currency = address(currency); + exampleInitData.referralFee = 0; + exampleInitData.followerOnly = false; + exampleInitData.endTimestamp = 0; + exampleInitData.recipient = me; + } + + function hubPostWithRevert(bytes4 expectedError) public virtual { + vm.expectRevert(expectedError); + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: getEncodedInitData(), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + + // Negatives + function testCannotPostWithNonWhitelistedCurrency() public { + exampleInitData.currency = address(0); + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + // We don't test for zero recipient here for two reasons: + // 1) Allows burning tokens + // 2) Inherited modules might not use the recipient field and leave it zero + // + // function testCannotPostWithZeroAddressRecipient() public { + // exampleInitData.recipient = address(0); + // hubPostWithRevert(Errors.InitParamsInvalid.selector); + // } + + function testCannotPostWithReferralFeeGreaterThanMaxBPS() public { + exampleInitData.referralFee = TREASURY_FEE_MAX_BPS + 1; + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + function testCannotPostWithPastNonzeroTimestamp() public { + vm.warp(1666666666); + exampleInitData.endTimestamp = uint40(block.timestamp) - 1; + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + function testCannotPostIfCalledFromNonHubAddress() public { + vm.expectRevert(Errors.NotHub.selector); + SimpleFeeCollectModule(baseFeeCollectModule).initializePublicationCollectModule( + userProfileId, + 1, + getEncodedInitData() + ); + } + + function testCannotPostWithWrongInitDataFormat() public { + vm.expectRevert(); + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: abi.encode(DEFAULT_COLLECT_LIMIT, REFERRAL_FEE_BPS, true), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + + // Scenarios + function testCreatePublicationWithCorrectInitData() public { + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: getEncodedInitData(), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + + function testCreatePublicationEmitsExpectedEvents() public { + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: getEncodedInitData(), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + assertEq(pubId, 1); + } + + function testFuzzCreatePublicationWithDifferentInitData( + uint160 amount, + uint96 collectLimit, + uint16 referralFee, + bool followerOnly, + uint72 endTimestamp + ) public virtual { + referralFee = uint16(bound(referralFee, 0, TREASURY_FEE_MAX_BPS)); + vm.assume(endTimestamp > block.timestamp || endTimestamp == 0); + + BaseFeeCollectModuleInitData memory fuzzyInitData = BaseFeeCollectModuleInitData({ + amount: amount, + collectLimit: collectLimit, + currency: address(currency), + referralFee: referralFee, + followerOnly: followerOnly, + endTimestamp: endTimestamp, + recipient: me + }); + + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: abi.encode(fuzzyInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + + function testFuzzFetchedPublicationDataShouldBeAccurate( + uint160 amount, + uint96 collectLimit, + uint16 referralFee, + bool followerOnly, + uint72 endTimestamp + ) public virtual { + referralFee = uint16(bound(referralFee, 0, TREASURY_FEE_MAX_BPS)); + endTimestamp = uint72(bound(endTimestamp, block.timestamp + 1, type(uint72).max)); + + BaseFeeCollectModuleInitData memory fuzzyInitData = BaseFeeCollectModuleInitData({ + amount: amount, + collectLimit: collectLimit, + currency: address(currency), + referralFee: referralFee, + followerOnly: followerOnly, + endTimestamp: endTimestamp, + recipient: me + }); + + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: abi.encode(fuzzyInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + assert(pubId > 0); + BaseProfilePublicationData memory fetchedData = SimpleFeeCollectModule(baseFeeCollectModule) + .getPublicationData(userProfileId, pubId); + assertEq(fetchedData.currency, fuzzyInitData.currency); + assertEq(fetchedData.amount, fuzzyInitData.amount); + assertEq(fetchedData.referralFee, fuzzyInitData.referralFee); + assertEq(fetchedData.followerOnly, fuzzyInitData.followerOnly); + assertEq(fetchedData.endTimestamp, fuzzyInitData.endTimestamp); + assertEq(fetchedData.collectLimit, fuzzyInitData.collectLimit); + assertEq(fetchedData.recipient, fuzzyInitData.recipient); + } +} + +////////////// +// Collect with BaseFeeCollectModule +// +contract BaseFeeCollectModule_Collect is BaseFeeCollectModuleBase { + uint256 immutable publisherProfileId; + uint256 immutable userProfileId; + + uint256 pubId; + + constructor() BaseFeeCollectModuleBase() { + publisherProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: publisher, + handle: 'pub', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + + userProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: user, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + } + + function setUp() public virtual { + exampleInitData.amount = 1 ether; + exampleInitData.collectLimit = 0; + exampleInitData.currency = address(currency); + exampleInitData.referralFee = 0; + exampleInitData.followerOnly = false; + exampleInitData.endTimestamp = 0; + exampleInitData.recipient = me; + + vm.prank(publisher); + pubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: getEncodedInitData(), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + currency.mint(user, type(uint256).max); + vm.prank(user); + currency.approve(baseFeeCollectModule, type(uint256).max); + } + + // Negatives + + function testCannotCollectIfCalledFromNonHubAddress() public { + vm.expectRevert(Errors.NotHub.selector); + SimpleFeeCollectModule(baseFeeCollectModule).processCollect( + publisherProfileId, + me, + publisherProfileId, + pubId, + abi.encode(address(currency), 1 ether) + ); + } + + function testCannotCollectNonExistentPublication() public { + vm.prank(user); + vm.expectRevert(Errors.PublicationDoesNotExist.selector); + hub.collect(publisherProfileId, pubId + 1, abi.encode(address(currency), 1 ether)); + } + + function testCannotCollectPassingWrongAmountInData() public { + vm.prank(user); + vm.expectRevert(Errors.ModuleDataMismatch.selector); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), 0.5 ether)); + } + + function testCannotCollectPassingWrongCurrencyInData() public { + vm.prank(user); + vm.expectRevert(Errors.ModuleDataMismatch.selector); + hub.collect(publisherProfileId, pubId, abi.encode(address(0xdead), 1 ether)); + } + + function testCannotCollectWithoutEnoughApproval() public { + vm.startPrank(user); + currency.approve(baseFeeCollectModule, 0); + assert(currency.allowance(user, baseFeeCollectModule) < 1 ether); + vm.expectRevert('ERC20: insufficient allowance'); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function testCannotCollectWithoutEnoughBalance() public { + vm.startPrank(user); + currency.transfer(address(1), currency.balanceOf(user)); + assertEq(currency.balanceOf(user), 0); + assert(currency.allowance(user, baseFeeCollectModule) >= 1 ether); + vm.expectRevert('ERC20: transfer amount exceeds balance'); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function hubPost() public virtual returns (uint256) { + vm.prank(publisher); + uint256 newPubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: getEncodedInitData(), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + return newPubId; + } + + function testCannotCollectIfNotAFollower() public { + exampleInitData.followerOnly = true; + uint256 secondPubId = hubPost(); + vm.startPrank(user); + vm.expectRevert(Errors.FollowInvalid.selector); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function testCannotCollectAfterEndTimestamp() public { + exampleInitData.endTimestamp = uint72(block.timestamp) + 100; + uint256 secondPubId = hubPost(); + + vm.warp(exampleInitData.endTimestamp + 1); + + vm.startPrank(user); + vm.expectRevert(Errors.CollectExpired.selector); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function testCannotCollectMoreThanLimit() public { + exampleInitData.collectLimit = 3; + uint256 secondPubId = hubPost(); + + vm.startPrank(user); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.expectRevert(Errors.MintLimitExceeded.selector); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + //Scenarios + + function testCanCollectIfAllConditionsAreMet() public { + uint256 secondPubId = hubPost(); + vm.startPrank(user); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function testProperEventsAreEmittedAfterCollect() public { + uint256 secondPubId = hubPost(); + vm.startPrank(user); + + vm.expectEmit(true, true, true, false); + emit Events.Collected( + user, + publisherProfileId, + secondPubId, + publisherProfileId, + secondPubId, + '', + block.timestamp + ); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + + vm.stopPrank(); + } + + function testCurrentCollectsIncreaseProperlyWhenCollecting() public virtual { + uint256 secondPubId = hubPost(); + vm.startPrank(user); + + BaseProfilePublicationData memory fetchedData = IBaseFeeCollectModule(baseFeeCollectModule) + .getBasePublicationData(publisherProfileId, secondPubId); + assertEq(fetchedData.currentCollects, 0); + + for (uint256 collects = 1; collects < 5; collects++) { + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + fetchedData = IBaseFeeCollectModule(baseFeeCollectModule).getBasePublicationData( + publisherProfileId, + secondPubId + ); + assertEq(fetchedData.currentCollects, collects); + } + vm.stopPrank(); + } +} + +contract BaseFeeCollectModule_Mirror is BaseFeeCollectModuleBase, BaseFeeCollectModule_Collect { + uint256 immutable userTwoProfileId; + uint256 origPubId; + + constructor() BaseFeeCollectModule_Collect() { + userTwoProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: userTwo, + handle: 'usertwo.lens', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + } + + function setUp() public override { + exampleInitData.amount = 1 ether; + exampleInitData.collectLimit = 0; + exampleInitData.currency = address(currency); + exampleInitData.referralFee = 0; + exampleInitData.followerOnly = false; + exampleInitData.endTimestamp = 0; + exampleInitData.recipient = me; + + vm.prank(userTwo); + origPubId = hub.post( + DataTypes.PostData({ + profileId: userTwoProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: getEncodedInitData(), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + vm.prank(publisher); + pubId = hub.mirror( + DataTypes.MirrorData({ + profileId: publisherProfileId, + profileIdPointed: userTwoProfileId, + pubIdPointed: origPubId, + referenceModule: address(0), + referenceModuleInitData: '', + referenceModuleData: '' + }) + ); + + currency.mint(user, type(uint256).max); + vm.prank(user); + currency.approve(baseFeeCollectModule, type(uint256).max); + } + + function hubPost() public override returns (uint256) { + vm.prank(userTwo); + origPubId = hub.post( + DataTypes.PostData({ + profileId: userTwoProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: getEncodedInitData(), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + vm.prank(publisher); + uint256 mirrorId = hub.mirror( + DataTypes.MirrorData({ + profileId: publisherProfileId, + profileIdPointed: userTwoProfileId, + pubIdPointed: origPubId, + referenceModule: address(0), + referenceModuleInitData: '', + referenceModuleData: '' + }) + ); + return mirrorId; + } + + function testCurrentCollectsIncreaseProperlyWhenCollecting() public override { + uint256 secondPubId = hubPost(); + vm.startPrank(user); + + BaseProfilePublicationData memory fetchedData = IBaseFeeCollectModule(baseFeeCollectModule) + .getBasePublicationData(userTwoProfileId, origPubId); + assertEq(fetchedData.currentCollects, 0); + + for (uint256 collects = 1; collects < 5; collects++) { + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + fetchedData = IBaseFeeCollectModule(baseFeeCollectModule).getBasePublicationData( + userTwoProfileId, + origPubId + ); + assertEq(fetchedData.currentCollects, collects); + } + vm.stopPrank(); + } +} + +contract BaseFeeCollectModule_FeeDistribution is BaseFeeCollectModuleBase { + struct Balances { + uint256 treasury; + uint256 referral; + uint256 publisher; + uint256 user; + uint256 userTwo; + } + + uint256 immutable publisherProfileId; + uint256 immutable userProfileId; + uint256 immutable mirrorerProfileId; + + constructor() BaseFeeCollectModuleBase() { + publisherProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: publisher, + handle: 'pub', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + + userProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: user, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + + mirrorerProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: userTwo, + handle: 'usertwo.lens', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + } + + function setUp() public virtual { + exampleInitData.amount = 1 ether; + exampleInitData.collectLimit = 0; + exampleInitData.currency = address(currency); + exampleInitData.referralFee = 0; + exampleInitData.followerOnly = false; + exampleInitData.endTimestamp = 0; + exampleInitData.recipient = publisher; + + currency.mint(user, type(uint256).max); + vm.prank(user); + currency.approve(baseFeeCollectModule, type(uint256).max); + } + + function hubPostAndMirror(uint16 referralFee, uint128 amount) + public + returns (uint256, uint256) + { + exampleInitData.referralFee = referralFee; + exampleInitData.amount = amount; + vm.prank(publisher); + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: getEncodedInitData(), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + vm.prank(userTwo); + uint256 mirrorId = hub.mirror( + DataTypes.MirrorData({ + profileId: mirrorerProfileId, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + referenceModule: address(0), + referenceModuleInitData: '', + referenceModuleData: '' + }) + ); + return (pubId, mirrorId); + } + + function verifyFeesWithoutMirror(uint16 treasuryFee, uint128 amount) public { + vm.prank(governance); + moduleGlobals.setTreasuryFee(treasuryFee); + (uint256 pubId, ) = hubPostAndMirror(0, amount); + + Balances memory balancesBefore; + Balances memory balancesAfter; + Balances memory balancesChange; + + balancesBefore.treasury = currency.balanceOf(treasury); + balancesBefore.publisher = currency.balanceOf(publisher); + balancesBefore.user = currency.balanceOf(user); + + vm.prank(user); + vm.recordLogs(); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), amount)); + Vm.Log[] memory entries = vm.getRecordedLogs(); + + balancesAfter.treasury = currency.balanceOf(treasury); + balancesAfter.publisher = currency.balanceOf(publisher); + balancesAfter.user = currency.balanceOf(user); + + balancesChange.treasury = balancesAfter.treasury - balancesBefore.treasury; + balancesChange.publisher = balancesAfter.publisher - balancesBefore.publisher; + balancesChange.user = balancesBefore.user - balancesAfter.user; + + assertEq(balancesChange.treasury + balancesChange.publisher, balancesChange.user); + + uint256 treasuryAmount = (uint256(amount) * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = amount - treasuryAmount; + + assertEq(balancesChange.treasury, treasuryAmount); + assertEq(balancesChange.publisher, adjustedAmount); + assertEq(balancesChange.user, amount); + + if (amount == 0 || adjustedAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, publisher); + assertEq(balancesChange.treasury, 0); + assertEq(balancesChange.publisher, 0); + assertEq(balancesChange.user, 0); + } else { + uint256 ownerFeeTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + publisher + ); + assertEq(ownerFeeTransferEventAmount, adjustedAmount); + } + if (treasuryFee == 0 || treasuryAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, treasury); + assertEq(balancesChange.treasury, 0); + } else { + uint256 treasuryTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + treasury + ); + assertEq(treasuryTransferEventAmount, treasuryAmount); + } + } + + function verifyFeesWithMirror( + uint16 treasuryFee, + uint16 referralFee, + uint128 amount + ) public { + vm.prank(governance); + moduleGlobals.setTreasuryFee(treasuryFee); + (, uint256 mirrorId) = hubPostAndMirror(referralFee, amount); + + Vm.Log[] memory entries; + + Balances memory balancesBefore; + Balances memory balancesAfter; + Balances memory balancesChange; + + balancesBefore.treasury = currency.balanceOf(treasury); + balancesBefore.referral = currency.balanceOf(userTwo); + balancesBefore.publisher = currency.balanceOf(publisher); + balancesBefore.user = currency.balanceOf(user); + + vm.recordLogs(); + vm.prank(user); + hub.collect(mirrorerProfileId, mirrorId, abi.encode(address(currency), amount)); + entries = vm.getRecordedLogs(); + + balancesAfter.treasury = currency.balanceOf(treasury); + balancesAfter.referral = currency.balanceOf(userTwo); + balancesAfter.publisher = currency.balanceOf(publisher); + balancesAfter.user = currency.balanceOf(user); + + balancesChange.treasury = balancesAfter.treasury - balancesBefore.treasury; + balancesChange.referral = balancesAfter.referral - balancesBefore.referral; + balancesChange.publisher = balancesAfter.publisher - balancesBefore.publisher; + balancesChange.user = balancesBefore.user - balancesAfter.user; + + assertEq( + balancesChange.treasury + balancesChange.referral + balancesChange.publisher, + balancesChange.user + ); + + uint256 treasuryAmount = (uint256(amount) * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = uint256(amount) - treasuryAmount; + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + + if (referralFee != 0) adjustedAmount = adjustedAmount - referralAmount; + + assertEq(balancesChange.treasury, treasuryAmount); + assertEq(balancesChange.referral, referralAmount); + assertEq(balancesChange.publisher, adjustedAmount); + assertEq(balancesChange.user, amount); + + if (amount == 0 || adjustedAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, publisher); + assertEq(balancesChange.treasury, 0); + assertEq(balancesChange.referral, 0); + assertEq(balancesChange.publisher, 0); + assertEq(balancesChange.user, 0); + } else { + uint256 ownerFeeTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + publisher + ); + assertEq(ownerFeeTransferEventAmount, adjustedAmount); + } + + if (treasuryFee == 0 || treasuryAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, treasury); + assertEq(balancesChange.treasury, 0); + } else { + uint256 treasuryTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + treasury + ); + assertEq(treasuryTransferEventAmount, treasuryAmount); + } + + if (referralFee == 0 || referralAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, userTwo); + assertEq(balancesChange.referral, referralAmount); + } else { + uint256 referralTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + userTwo + ); + assertEq(referralTransferEventAmount, referralAmount); + } + } + + function testFeesDistributionEdgeCasesWithoutMirror() public virtual { + verifyFeesWithoutMirror(0, 0); + verifyFeesWithoutMirror(0, 1 ether); + verifyFeesWithoutMirror(0, type(uint128).max); + verifyFeesWithoutMirror(BPS_MAX / 2 - 1, 0); + verifyFeesWithoutMirror(BPS_MAX / 2 - 1, 1 ether); + verifyFeesWithoutMirror(BPS_MAX / 2 - 1, type(uint128).max); + } + + function testFeesDistributionWithoutMirrorFuzzing(uint16 treasuryFee, uint128 amount) + public + virtual + { + treasuryFee = uint16(bound(treasuryFee, 0, BPS_MAX / 2 - 2)); + verifyFeesWithoutMirror(treasuryFee, amount); + } + + function testFeesDistributionEdgeCasesWithMirror() public virtual { + verifyFeesWithMirror(0, 0, 0); + verifyFeesWithMirror(0, 0, type(uint128).max); + verifyFeesWithMirror(0, BPS_MAX / 2 - 1, 0); + verifyFeesWithMirror(0, BPS_MAX / 2 - 1, type(uint128).max); + verifyFeesWithMirror(BPS_MAX / 2 - 1, 0, 0); + verifyFeesWithMirror(BPS_MAX / 2 - 1, 0, type(uint128).max); + verifyFeesWithMirror(BPS_MAX / 2 - 1, BPS_MAX / 2 - 1, 0); + verifyFeesWithMirror(BPS_MAX / 2 - 1, BPS_MAX / 2 - 1, type(uint128).max); + verifyFeesWithMirror(0, 0, 1); + verifyFeesWithMirror(0, 1, 0); + verifyFeesWithMirror(0, 1, 1); + verifyFeesWithMirror(1, 0, 1); + verifyFeesWithMirror(1, 1, 0); + verifyFeesWithMirror(1, 1, 1); + } + + function testFeesDistributionWithMirrorFuzzing( + uint16 treasuryFee, + uint16 referralFee, + uint128 amount + ) public virtual { + treasuryFee = uint16(bound(treasuryFee, 0, BPS_MAX / 2 - 2)); + referralFee = uint16(bound(referralFee, 0, BPS_MAX / 2 - 2)); + verifyFeesWithMirror(treasuryFee, referralFee, amount); + } +} + +///////// +// Publication Creation with BaseFeeCollectModule +// +contract BaseFeeCollectModule_GasReport is BaseFeeCollectModuleBase { + uint256 immutable userProfileId; + + constructor() BaseFeeCollectModuleBase() { + userProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: me, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + } + + function testCreatePublicationWithDifferentInitData() public { + uint96 collectLimit = 10; + bool followerOnly = false; + uint72 endTimestamp = uint72(block.timestamp + 100); + + for (uint16 referralFee = 0; referralFee <= BPS_MAX; referralFee++) { + if (referralFee >= 2) referralFee += BPS_MAX / 4; + if (referralFee > 9000) referralFee = BPS_MAX; + for (uint160 amount = 0; amount < type(uint160).max; amount++) { + if (amount >= 2) amount += 1 ether; + if (amount >= 2 ether) amount = type(uint160).max - 1; + + exampleInitData.amount = amount; + exampleInitData.collectLimit = collectLimit; + exampleInitData.currency = address(currency); + exampleInitData.referralFee = referralFee; + exampleInitData.followerOnly = followerOnly; + exampleInitData.endTimestamp = endTimestamp; + exampleInitData.recipient = me; + + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: baseFeeCollectModule, + collectModuleInitData: getEncodedInitData(), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + } + } +} diff --git a/lens-protocol/modules/test/foundry/collect/MultirecipientCollectModule.base.sol b/lens-protocol/modules/test/foundry/collect/MultirecipientCollectModule.base.sol new file mode 100644 index 0000000..d8e5885 --- /dev/null +++ b/lens-protocol/modules/test/foundry/collect/MultirecipientCollectModule.base.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import 'forge-std/Test.sol'; +import './BaseFeeCollectModule.base.sol'; +import 'contracts/collect/MultirecipientFeeCollectModule.sol'; + +contract MultirecipientCollectModuleBase is BaseFeeCollectModuleBase { + using stdJson for string; + uint16 constant BPS_MAX = 10000; + uint256 MAX_RECIPIENTS = 5; + + MultirecipientFeeCollectModule multirecipientFeeCollectModule; + MultirecipientFeeCollectModuleInitData multirecipientExampleInitData; + + // Deploy & Whitelist MultirecipientFeeCollectModule + constructor() { + if ( + fork && + keyExists(string(abi.encodePacked('.', forkEnv, '.MultirecipientFeeCollectModule'))) + ) { + multirecipientFeeCollectModule = MultirecipientFeeCollectModule( + json.readAddress( + string(abi.encodePacked('.', forkEnv, '.MultirecipientFeeCollectModule')) + ) + ); + console.log( + 'Testing against already deployed module at:', + address(multirecipientFeeCollectModule) + ); + } else { + vm.prank(deployer); + multirecipientFeeCollectModule = new MultirecipientFeeCollectModule( + hubProxyAddr, + address(moduleGlobals) + ); + } + baseFeeCollectModule = address(multirecipientFeeCollectModule); + vm.startPrank(governance); + hub.whitelistCollectModule(address(multirecipientFeeCollectModule), true); + vm.stopPrank(); + } + + function getEncodedInitData() internal virtual override returns (bytes memory) { + multirecipientExampleInitData.amount = exampleInitData.amount; + multirecipientExampleInitData.collectLimit = exampleInitData.collectLimit; + multirecipientExampleInitData.currency = exampleInitData.currency; + multirecipientExampleInitData.referralFee = exampleInitData.referralFee; + multirecipientExampleInitData.followerOnly = exampleInitData.followerOnly; + multirecipientExampleInitData.endTimestamp = exampleInitData.endTimestamp; + if (multirecipientExampleInitData.recipients.length == 0) + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: exampleInitData.recipient, split: BPS_MAX}) + ); + + return abi.encode(multirecipientExampleInitData); + } +} diff --git a/lens-protocol/modules/test/foundry/collect/MultirecipientCollectModule.test.sol b/lens-protocol/modules/test/foundry/collect/MultirecipientCollectModule.test.sol new file mode 100644 index 0000000..f2f2980 --- /dev/null +++ b/lens-protocol/modules/test/foundry/collect/MultirecipientCollectModule.test.sol @@ -0,0 +1,509 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import '../BaseSetup.t.sol'; +import {MultirecipientCollectModuleBase} from './MultirecipientCollectModule.base.sol'; +import '../helpers/TestHelpers.sol'; +import {RecipientSplitCannotBeZero, TooManyRecipients, InvalidRecipientSplits, MultirecipientFeeCollectProfilePublicationData, MultirecipientFeeCollectModuleInitData, RecipientData, MultirecipientFeeCollectModule} from 'contracts/collect/MultirecipientFeeCollectModule.sol'; +import '@aave/lens-protocol/contracts/libraries/Events.sol'; +import {BaseFeeCollectModule_Publication, BaseFeeCollectModule_Collect, BaseFeeCollectModule_Mirror, BaseFeeCollectModule_FeeDistribution} from './BaseFeeCollectModule.test.sol'; +import {BaseFeeCollectModuleBase} from './BaseFeeCollectModule.base.sol'; + +///////// +// Publication Creation with InheritedFeeCollectModule +// +contract MultirecipientCollectModule_Publication is + MultirecipientCollectModuleBase, + BaseFeeCollectModule_Publication +{ + constructor() {} + + function getEncodedInitData() + internal + override(MultirecipientCollectModuleBase, BaseFeeCollectModuleBase) + returns (bytes memory) + { + return MultirecipientCollectModuleBase.getEncodedInitData(); + } + + function testCannotPostWithZeroAmount() public { + exampleInitData.amount = 0; + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + function testCannotPostWithoutRecipients() public { + delete multirecipientExampleInitData.recipients; + vm.expectRevert(Errors.InitParamsInvalid.selector); + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(baseFeeCollectModule), + collectModuleInitData: abi.encode(multirecipientExampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + + function testCannotPostWithZeroAddressRecipient() public { + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: address(0), split: BPS_MAX}) + ); + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + function testCannotPostWithOneOfRecipientsAddressIsZero() public { + delete multirecipientExampleInitData.recipients; + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: me, split: BPS_MAX / 4}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: me, split: BPS_MAX / 4}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: address(0), split: BPS_MAX / 4}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: me, split: BPS_MAX / 4}) + ); + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + function testCannotPostWithMoreThanMaxRecipients() public { + delete multirecipientExampleInitData.recipients; + assertEq(multirecipientExampleInitData.recipients.length, 0); + uint16 splitUsed; + for (uint256 i = 0; i < MAX_RECIPIENTS; i++) { + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: me, split: 1000}) + ); + splitUsed += 1000; + } + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: me, split: BPS_MAX - splitUsed}) + ); + assert(multirecipientExampleInitData.recipients.length > MAX_RECIPIENTS); + hubPostWithRevert(TooManyRecipients.selector); + } + + function testCannotPostWithRecipientSplitsSumNotEqualToBPS_MAX() public { + delete multirecipientExampleInitData.recipients; + assertEq(multirecipientExampleInitData.recipients.length, 0); + uint16 splitUsed; + for (uint256 i = 0; i < MAX_RECIPIENTS; i++) { + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: me, split: 1000}) + ); + splitUsed += 1000; + } + assert(splitUsed != BPS_MAX); + hubPostWithRevert(InvalidRecipientSplits.selector); + } + + function testCannotPostWithOneRecipientAndSplitNotEqualToBPS_MAX() public { + delete multirecipientExampleInitData.recipients; + multirecipientExampleInitData.recipients.push(RecipientData({recipient: me, split: 9000})); + hubPostWithRevert(InvalidRecipientSplits.selector); + } + + function testCannotPostWithZeroRecipientSplit() public { + delete multirecipientExampleInitData.recipients; + assertEq(multirecipientExampleInitData.recipients.length, 0); + uint16 splitUsed; + for (uint256 i = 0; i < MAX_RECIPIENTS; i++) { + if (i != 3) { + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: me, split: 2500}) + ); + splitUsed += 2500; + } else { + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: me, split: 0}) + ); + } + } + assert(splitUsed == BPS_MAX); + hubPostWithRevert(RecipientSplitCannotBeZero.selector); + } + + function testFuzzFetchedPublicationDataShouldBeAccurate( + uint160 amount, + uint96 collectLimit, + uint16 referralFee, + bool followerOnly, + uint72 endTimestamp + ) public override {} + + function testFuzzFetchedPublicationDataShouldBeAccurate( + uint160 amount, + uint96 collectLimit, + uint16 referralFee, + bool followerOnly, + uint72 endTimestamp, + uint8 recipientsNumber + ) public { + vm.assume(amount != 0); + referralFee = uint16(bound(referralFee, 0, TREASURY_FEE_MAX_BPS)); + endTimestamp = uint72(bound(endTimestamp, block.timestamp + 1, type(uint72).max)); + recipientsNumber = uint8(bound(recipientsNumber, 1, 5)); + + RecipientData[] memory recipients = new RecipientData[](recipientsNumber); + uint16 sum; + for (uint16 i = 0; i < recipientsNumber; i++) { + uint16 split = BPS_MAX / recipientsNumber; + sum += split; + if (i == recipientsNumber - 1 && sum != BPS_MAX) split += BPS_MAX - sum; + recipients[i] = RecipientData({recipient: me, split: split}); + } + + MultirecipientFeeCollectModuleInitData + memory fuzzyInitData = MultirecipientFeeCollectModuleInitData({ + amount: amount, + collectLimit: collectLimit, + currency: address(currency), + referralFee: referralFee, + followerOnly: followerOnly, + endTimestamp: endTimestamp, + recipients: recipients + }); + + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(multirecipientFeeCollectModule), + collectModuleInitData: abi.encode(fuzzyInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + assert(pubId > 0); + MultirecipientFeeCollectProfilePublicationData + memory fetchedData = multirecipientFeeCollectModule.getPublicationData( + userProfileId, + pubId + ); + assertEq(fetchedData.currency, fuzzyInitData.currency); + assertEq(fetchedData.amount, fuzzyInitData.amount); + assertEq(fetchedData.referralFee, fuzzyInitData.referralFee); + assertEq(fetchedData.followerOnly, fuzzyInitData.followerOnly); + assertEq(fetchedData.endTimestamp, fuzzyInitData.endTimestamp); + assertEq(fetchedData.collectLimit, fuzzyInitData.collectLimit); + for (uint256 i = 0; i < recipientsNumber; i++) { + assertEq(fetchedData.recipients[i].recipient, fuzzyInitData.recipients[i].recipient); + assertEq(fetchedData.recipients[i].split, fuzzyInitData.recipients[i].split); + } + } + + function testFuzzCreatePublicationWithDifferentInitData( + uint160 amount, + uint96 collectLimit, + uint16 referralFee, + bool followerOnly, + uint72 endTimestamp + ) public override {} + + function testFuzzCreatePublicationWithDifferentInitData( + uint160 amount, + uint96 collectLimit, + uint16 referralFee, + bool followerOnly, + uint72 endTimestamp, + uint8 recipientsNumber + ) public { + vm.assume(amount != 0); + referralFee = uint16(bound(referralFee, 0, TREASURY_FEE_MAX_BPS)); + vm.assume(endTimestamp > block.timestamp || endTimestamp == 0); + recipientsNumber = uint8(bound(recipientsNumber, 1, 5)); + + RecipientData[] memory recipients = new RecipientData[](recipientsNumber); + uint16 sum; + for (uint16 i = 0; i < recipientsNumber; i++) { + uint16 split = BPS_MAX / recipientsNumber; + sum += split; + if (i == recipientsNumber - 1 && sum != BPS_MAX) split += BPS_MAX - sum; + recipients[i] = RecipientData({recipient: me, split: split}); + } + + MultirecipientFeeCollectModuleInitData + memory fuzzyInitData = MultirecipientFeeCollectModuleInitData({ + amount: amount, + collectLimit: collectLimit, + currency: address(currency), + referralFee: referralFee, + followerOnly: followerOnly, + endTimestamp: endTimestamp, + recipients: recipients + }); + + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(multirecipientFeeCollectModule), + collectModuleInitData: abi.encode(fuzzyInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } +} + +////////////// +// Collect with InheritedFeeCollectModule +// +contract MultirecipientCollectModule_Collect is + MultirecipientCollectModuleBase, + BaseFeeCollectModule_Collect +{ + constructor() {} + + function getEncodedInitData() + internal + override(MultirecipientCollectModuleBase, BaseFeeCollectModuleBase) + returns (bytes memory) + { + return MultirecipientCollectModuleBase.getEncodedInitData(); + } +} + +////////////// +// Collect on Mirror with InheritedFeeCollectModule +// +contract MultirecipientCollectModule_Mirror is + MultirecipientCollectModuleBase, + BaseFeeCollectModule_Mirror +{ + constructor() {} + + function getEncodedInitData() + internal + override(MultirecipientCollectModuleBase, BaseFeeCollectModuleBase) + returns (bytes memory) + { + return MultirecipientCollectModuleBase.getEncodedInitData(); + } +} + +////////////// +// Fee Distribution of InheritedFeeCollectModule +// +contract MultirecipientCollectModule_FeeDistribution is + MultirecipientCollectModuleBase, + BaseFeeCollectModule_FeeDistribution +{ + constructor() {} + + struct InheritedBalances { + uint256 treasury; + uint256 referral; + uint256 publisher; + uint256 user; + uint256 userTwo; + uint256 userThree; + uint256 userFour; + uint256 userFive; + } + + function getEncodedInitData() + internal + override(MultirecipientCollectModuleBase, BaseFeeCollectModuleBase) + returns (bytes memory) + { + return MultirecipientCollectModuleBase.getEncodedInitData(); + } + + function testFeeSplitEquallyWithFiveRecipients(uint128 totalCollectFee) public { + vm.assume(totalCollectFee != 0); + uint256 treasuryAmount = (uint256(totalCollectFee) * TREASURY_FEE_BPS) / BPS_MAX; + uint256 adjustedAmount = totalCollectFee - treasuryAmount; + + uint16 splitPerUser = BPS_MAX / 5; + uint256 expectedUserFeeCut = adjustedAmount / 5; + + InheritedBalances memory balancesBefore; + InheritedBalances memory balancesAfter; + + // Set users in initData to publisher, u2, u3, u4, userFive with equal split of fee + delete multirecipientExampleInitData.recipients; + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: publisher, split: splitPerUser}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: userTwo, split: splitPerUser}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: userThree, split: splitPerUser}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: userFour, split: splitPerUser}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: userFive, split: splitPerUser}) + ); + + (uint256 pubId, ) = hubPostAndMirror(0, totalCollectFee); + + balancesBefore.treasury = currency.balanceOf(treasury); + balancesBefore.publisher = currency.balanceOf(publisher); + balancesBefore.userTwo = currency.balanceOf(userTwo); + balancesBefore.userThree = currency.balanceOf(userThree); + balancesBefore.userFour = currency.balanceOf(userFour); + balancesBefore.userFive = currency.balanceOf(userFive); + + vm.prank(user); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), totalCollectFee)); + + balancesAfter.treasury = currency.balanceOf(treasury); + balancesAfter.publisher = currency.balanceOf(publisher); + balancesAfter.userTwo = currency.balanceOf(userTwo); + balancesAfter.userThree = currency.balanceOf(userThree); + balancesAfter.userFour = currency.balanceOf(userFour); + balancesAfter.userFive = currency.balanceOf(userFive); + + assertEq(balancesAfter.treasury - balancesBefore.treasury, treasuryAmount); + assertEq(balancesAfter.publisher - balancesBefore.publisher, expectedUserFeeCut); + assertEq(balancesAfter.userTwo - balancesBefore.userTwo, expectedUserFeeCut); + assertEq(balancesAfter.userThree - balancesBefore.userThree, expectedUserFeeCut); + assertEq(balancesAfter.userFour - balancesBefore.userFour, expectedUserFeeCut); + assertEq(balancesAfter.userFive - balancesBefore.userFive, expectedUserFeeCut); + } + + function testFuzzedSplitCutsWithFiveRecipients( + uint128 totalCollectFee, + uint16 userTwoSplit, + uint16 extraSplit + ) public { + vm.assume(totalCollectFee != 0); + userTwoSplit = uint16(bound(userTwoSplit, 1, BPS_MAX / 2 - 1)); + extraSplit = uint16(bound(extraSplit, 2, BPS_MAX / 2 - 1)); + + uint256 treasuryAmount = (uint256(totalCollectFee) * TREASURY_FEE_BPS) / BPS_MAX; + + // Some fuzzy randomness in the splits + uint16 publisherSplit = (BPS_MAX / 2) - userTwoSplit; + uint16 userThreeSplit = (BPS_MAX / 2) - extraSplit; + uint16 userFourSplit = extraSplit / 2; + uint16 userFiveSplit = extraSplit - userFourSplit; + + assertEq( + publisherSplit + userTwoSplit + userThreeSplit + userFourSplit + userFiveSplit, + BPS_MAX + ); + + InheritedBalances memory balancesBefore; + InheritedBalances memory balancesAfter; + + // Set users in initData to five recipients with fuzzed splits + delete multirecipientExampleInitData.recipients; + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: publisher, split: publisherSplit}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: userTwo, split: userTwoSplit}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: userThree, split: userThreeSplit}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: userFour, split: userFourSplit}) + ); + multirecipientExampleInitData.recipients.push( + RecipientData({recipient: userFive, split: userFiveSplit}) + ); + + (uint256 pubId, ) = hubPostAndMirror(0, totalCollectFee); + + balancesBefore.treasury = currency.balanceOf(treasury); + balancesBefore.publisher = currency.balanceOf(publisher); + balancesBefore.userTwo = currency.balanceOf(userTwo); + balancesBefore.userThree = currency.balanceOf(userThree); + balancesBefore.userFour = currency.balanceOf(userFour); + balancesBefore.userFive = currency.balanceOf(userFive); + + vm.prank(user); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), totalCollectFee)); + + balancesAfter.treasury = currency.balanceOf(treasury); + balancesAfter.publisher = currency.balanceOf(publisher); + balancesAfter.userTwo = currency.balanceOf(userTwo); + balancesAfter.userThree = currency.balanceOf(userThree); + balancesAfter.userFour = currency.balanceOf(userFour); + balancesAfter.userFive = currency.balanceOf(userFive); + + assertEq(balancesAfter.treasury - balancesBefore.treasury, treasuryAmount); + assertEq( + balancesAfter.publisher - balancesBefore.publisher, + predictCutAmount(totalCollectFee - treasuryAmount, publisherSplit) + ); + assertEq( + balancesAfter.userTwo - balancesBefore.userTwo, + predictCutAmount(totalCollectFee - treasuryAmount, userTwoSplit) + ); + assertEq( + balancesAfter.userThree - balancesBefore.userThree, + predictCutAmount(totalCollectFee - treasuryAmount, userThreeSplit) + ); + assertEq( + balancesAfter.userFour - balancesBefore.userFour, + predictCutAmount(totalCollectFee - treasuryAmount, userFourSplit) + ); + assertEq( + balancesAfter.userFive - balancesBefore.userFive, + predictCutAmount(totalCollectFee - treasuryAmount, userFiveSplit) + ); + } + + // Overriding some tests from Base to disable zero amounts: + + function testFeesDistributionWithMirrorFuzzing( + uint16 treasuryFee, + uint16 referralFee, + uint128 amount + ) public override { + vm.assume(amount != 0); + super.testFeesDistributionWithMirrorFuzzing(treasuryFee, referralFee, amount); + } + + function testFeesDistributionWithoutMirrorFuzzing(uint16 treasuryFee, uint128 amount) + public + override + { + vm.assume(amount != 0); + super.testFeesDistributionWithoutMirrorFuzzing(treasuryFee, amount); + } + + // Using 1 wei instead of zero here in (, amount): + function testFeesDistributionEdgeCasesWithoutMirror() public override { + verifyFeesWithoutMirror(0, 1); + verifyFeesWithoutMirror(0, 1 ether); + verifyFeesWithoutMirror(0, type(uint128).max); + verifyFeesWithoutMirror(BPS_MAX / 2 - 1, 1); + verifyFeesWithoutMirror(BPS_MAX / 2 - 1, 1 ether); + verifyFeesWithoutMirror(BPS_MAX / 2 - 1, type(uint128).max); + } + + // Using 1 wei instead of zero here in (, , amount): + function testFeesDistributionEdgeCasesWithMirror() public override { + verifyFeesWithMirror(0, 0, type(uint128).max); + verifyFeesWithMirror(0, BPS_MAX / 2 - 1, 1); + verifyFeesWithMirror(0, BPS_MAX / 2 - 1, type(uint128).max); + verifyFeesWithMirror(BPS_MAX / 2 - 1, 0, 1); + verifyFeesWithMirror(BPS_MAX / 2 - 1, 0, type(uint128).max); + verifyFeesWithMirror(BPS_MAX / 2 - 1, BPS_MAX / 2 - 1, 1); + verifyFeesWithMirror(BPS_MAX / 2 - 1, BPS_MAX / 2 - 1, type(uint128).max); + verifyFeesWithMirror(0, 0, 1); + verifyFeesWithMirror(0, 1, 1); + verifyFeesWithMirror(1, 0, 1); + verifyFeesWithMirror(1, 1, 1); + } + + function predictCutAmount(uint256 totalAfterTreasuryCut, uint16 cutBPS) + internal + pure + returns (uint256) + { + return (totalAfterTreasuryCut * cutBPS) / BPS_MAX; + } +} diff --git a/lens-protocol/modules/test/foundry/collect/StepwiseCollectModule.base.sol b/lens-protocol/modules/test/foundry/collect/StepwiseCollectModule.base.sol new file mode 100644 index 0000000..5d0d127 --- /dev/null +++ b/lens-protocol/modules/test/foundry/collect/StepwiseCollectModule.base.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import 'forge-std/Test.sol'; +import '../BaseSetup.t.sol'; +import 'contracts/collect/StepwiseCollectModule.sol'; + +contract StepwiseCollectModuleBase is BaseSetup { + using stdJson for string; + StepwiseCollectModule stepwiseCollectModule; + + uint256 constant DEFAULT_COLLECT_LIMIT = 3; + uint16 constant REFERRAL_FEE_BPS = 250; + + // Deploy & Whitelist StepwiseCollectModule + constructor() BaseSetup() { + if (fork && keyExists(string(abi.encodePacked('.', forkEnv, '.StepwiseCollectModule')))) { + stepwiseCollectModule = StepwiseCollectModule( + json.readAddress(string(abi.encodePacked('.', forkEnv, '.StepwiseCollectModule'))) + ); + console.log( + 'Testing against already deployed module at:', + address(stepwiseCollectModule) + ); + } else { + vm.prank(deployer); + stepwiseCollectModule = new StepwiseCollectModule(hubProxyAddr, address(moduleGlobals)); + } + vm.prank(governance); + hub.whitelistCollectModule(address(stepwiseCollectModule), true); + } +} diff --git a/lens-protocol/modules/test/foundry/collect/StepwiseCollectModule.test.sol b/lens-protocol/modules/test/foundry/collect/StepwiseCollectModule.test.sol new file mode 100644 index 0000000..53539f5 --- /dev/null +++ b/lens-protocol/modules/test/foundry/collect/StepwiseCollectModule.test.sol @@ -0,0 +1,1113 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import '../BaseSetup.t.sol'; +import {StepwiseCollectModuleBase} from './StepwiseCollectModule.base.sol'; +import '../helpers/TestHelpers.sol'; +import {ProfilePublicationData, StepwiseCollectModuleInitData, StepwiseCollectModule} from 'contracts/collect/StepwiseCollectModule.sol'; +import '@aave/lens-protocol/contracts/libraries/Events.sol'; + +///////// +// Publication Creation with StepwiseCollectModule +// +contract StepwiseCollectModule_Publication is StepwiseCollectModuleBase { + uint256 immutable userProfileId; + + StepwiseCollectModuleInitData exampleInitData; + + constructor() StepwiseCollectModuleBase() { + userProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: me, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + } + + function setUp() public { + exampleInitData = StepwiseCollectModuleInitData({ + collectLimit: 0, + currency: address(currency), + recipient: me, + referralFee: 0, + followerOnly: false, + endTimestamp: 0, + a: 0, + b: 0, + c: 1 ether + }); + } + + function hubPostWithRevert(bytes4 expectedError) public { + vm.expectRevert(expectedError); + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + + // Negatives + function testCannotPostWithNonWhitelistedCurrncy() public { + exampleInitData.currency = address(0); + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + function testCannotPostWithZeroRecipient() public { + exampleInitData.recipient = address(0); + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + function testCannotPostWithReferralFeeGreaterThanMaxBPS() public { + exampleInitData.referralFee = TREASURY_FEE_MAX_BPS + 1; + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + function testCannotPostWithPastNonzeroTimestamp() public { + vm.warp(1666666666); + exampleInitData.endTimestamp = uint40(block.timestamp) - 1; + hubPostWithRevert(Errors.InitParamsInvalid.selector); + } + + function testCannotPostIfCalledFromNonHubAddress() public { + vm.expectRevert(Errors.NotHub.selector); + stepwiseCollectModule.initializePublicationCollectModule( + userProfileId, + 1, + abi.encode(exampleInitData) + ); + } + + function testCannotPostWithWrongInitDataFormat() public { + vm.expectRevert(); + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(DEFAULT_COLLECT_LIMIT, REFERRAL_FEE_BPS, true), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + + // Scenarios + function testCreatePublicationWithCorrectInitData() public { + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + + function testCreatePublicationEmitsExpectedEvents() public { + vm.recordLogs(); + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + Vm.Log[] memory entries = vm.getRecordedLogs(); + uint256 eventPubId = TestHelpers.getCreatedPubIdFromEvents(entries); + assertEq(pubId, eventPubId); + } + + function testFuzzCreatePublicationWithDifferentInitData( + uint64 collectLimit, + uint16 referralFee, + bool followerOnly, + uint40 endTimestamp, + uint72 a, + uint56 b, + uint128 c + ) public { + referralFee = uint16(bound(referralFee, 0, TREASURY_FEE_MAX_BPS)); + endTimestamp = uint40(bound(endTimestamp, block.timestamp + 1, type(uint40).max)); + + StepwiseCollectModuleInitData memory fuzzyInitData = StepwiseCollectModuleInitData({ + collectLimit: collectLimit, + currency: address(currency), + recipient: me, + referralFee: referralFee, + followerOnly: followerOnly, + endTimestamp: endTimestamp, + a: a, + b: b, + c: c + }); + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(fuzzyInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + } + + function testFuzzFetchedPublicationDataShouldBeAccurate( + uint64 collectLimit, + uint16 referralFee, + bool followerOnly, + uint40 endTimestamp, + uint72 a, + uint56 b, + uint128 c + ) public { + referralFee = uint16(bound(referralFee, 0, TREASURY_FEE_MAX_BPS)); + endTimestamp = uint40(bound(endTimestamp, block.timestamp + 1, type(uint40).max)); + + StepwiseCollectModuleInitData memory fuzzyInitData = StepwiseCollectModuleInitData({ + collectLimit: collectLimit, + currency: address(currency), + recipient: me, + referralFee: referralFee, + followerOnly: followerOnly, + endTimestamp: endTimestamp, + a: a, + b: b, + c: c + }); + + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(fuzzyInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + assert(pubId > 0); + ProfilePublicationData memory fetchedData = stepwiseCollectModule.getPublicationData( + userProfileId, + pubId + ); + assertEq(fetchedData.currency, fuzzyInitData.currency); + assertEq(fetchedData.a, fuzzyInitData.a); + assertEq(fetchedData.referralFee, fuzzyInitData.referralFee); + assertEq(fetchedData.followerOnly, fuzzyInitData.followerOnly); + assertEq(fetchedData.recipient, fuzzyInitData.recipient); + assertEq(fetchedData.b, fuzzyInitData.b); + assertEq(fetchedData.endTimestamp, fuzzyInitData.endTimestamp); + assertEq(fetchedData.c, fuzzyInitData.c); + assertEq(fetchedData.collectLimit, fuzzyInitData.collectLimit); + } +} + +///////////// +// Collect with StepwiseCollectModule +// +contract StepwiseCollectModule_Collect is StepwiseCollectModuleBase { + uint256 immutable publisherProfileId; + uint256 immutable userProfileId; + + uint256 pubId; + + StepwiseCollectModuleInitData exampleInitData; + + constructor() StepwiseCollectModuleBase() { + publisherProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: publisher, + handle: 'pub', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + + userProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: user, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + } + + function setUp() public virtual { + exampleInitData = StepwiseCollectModuleInitData({ + collectLimit: 0, + currency: address(currency), + recipient: me, + referralFee: 0, + followerOnly: false, + endTimestamp: 0, + a: 0, + b: 0, + c: 1 ether + }); + + vm.prank(publisher); + pubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + currency.mint(user, type(uint256).max); + vm.prank(user); + currency.approve(address(stepwiseCollectModule), type(uint256).max); + } + + // Negatives + + function testCannotCollectIfCalledFromNonHubAddress() public { + vm.expectRevert(Errors.NotHub.selector); + stepwiseCollectModule.processCollect( + publisherProfileId, + me, + publisherProfileId, + pubId, + abi.encode(address(currency), 1 ether) + ); + } + + function testCannotCollectNonExistentPublication() public { + vm.prank(user); + vm.expectRevert(Errors.PublicationDoesNotExist.selector); + hub.collect(publisherProfileId, pubId + 1, abi.encode(address(currency), 1 ether)); + } + + function testCannotCollectPassingWrongAmountInData() public { + vm.prank(user); + vm.expectRevert(Errors.ModuleDataMismatch.selector); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), 0.5 ether)); + } + + function testCannotCollectPassingWrongCurrencyInData() public { + vm.prank(user); + vm.expectRevert(Errors.ModuleDataMismatch.selector); + hub.collect(publisherProfileId, pubId, abi.encode(address(0xdead), 1 ether)); + } + + function testCannotCollectWithoutEnoughApproval() public { + vm.startPrank(user); + currency.approve(address(stepwiseCollectModule), 0); + assert(currency.allowance(user, address(stepwiseCollectModule)) < 1 ether); + vm.expectRevert('ERC20: insufficient allowance'); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function testCannotCollectWithoutEnoughBalance() public { + vm.startPrank(user); + currency.transfer(address(1), currency.balanceOf(user)); + assertEq(currency.balanceOf(user), 0); + assert(currency.allowance(user, address(stepwiseCollectModule)) >= 1 ether); + vm.expectRevert('ERC20: transfer amount exceeds balance'); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function hubPost(StepwiseCollectModuleInitData memory initData) + public + virtual + returns (uint256) + { + vm.prank(publisher); + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(initData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + return pubId; + } + + function testCannotCollectIfNotAFollower() public { + exampleInitData.followerOnly = true; + uint256 secondPubId = hubPost(exampleInitData); + vm.startPrank(user); + vm.expectRevert(Errors.FollowInvalid.selector); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function testCannotCollectAfterEndTimestamp() public { + exampleInitData.endTimestamp = uint40(block.timestamp) + 100; + uint256 secondPubId = hubPost(exampleInitData); + + vm.warp(exampleInitData.endTimestamp + 1); + + vm.startPrank(user); + vm.expectRevert(Errors.CollectExpired.selector); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function testCannotCollectMoreThanLimit() public { + exampleInitData.collectLimit = 3; + uint256 secondPubId = hubPost(exampleInitData); + + vm.startPrank(user); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.expectRevert(Errors.MintLimitExceeded.selector); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + //Scenarios + + function testCanCollectIfAllConditionsAreMet() public { + uint256 secondPubId = hubPost(exampleInitData); + vm.startPrank(user); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + vm.stopPrank(); + } + + function testProperEventsAreEmittedAfterCollect() public { + uint256 secondPubId = hubPost(exampleInitData); + vm.startPrank(user); + + vm.expectEmit(true, true, true, false); + emit Events.Collected( + user, + publisherProfileId, + secondPubId, + publisherProfileId, + secondPubId, + '', + block.timestamp + ); + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + + vm.stopPrank(); + } + + function testCurrentCollectsIncreaseProperlyWhenCollecting() public virtual { + uint256 secondPubId = hubPost(exampleInitData); + vm.startPrank(user); + + ProfilePublicationData memory fetchedData = stepwiseCollectModule.getPublicationData( + publisherProfileId, + secondPubId + ); + assertEq(fetchedData.currentCollects, 0); + + for (uint256 collects = 1; collects < 5; collects++) { + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + fetchedData = stepwiseCollectModule.getPublicationData(publisherProfileId, secondPubId); + assertEq(fetchedData.currentCollects, collects); + } + vm.stopPrank(); + } +} + +///////////// +// Collect with StepwiseCollectModule from a Mirror +// +contract StepwiseCollectModule_Mirror is StepwiseCollectModuleBase, StepwiseCollectModule_Collect { + uint256 immutable userTwoProfileId; + uint256 origPubId; + + constructor() StepwiseCollectModule_Collect() { + userTwoProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: userTwo, + handle: 'usertwo.lens', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + } + + function setUp() public override { + exampleInitData = StepwiseCollectModuleInitData({ + collectLimit: 0, + currency: address(currency), + recipient: me, + referralFee: 0, + followerOnly: false, + endTimestamp: 0, + a: 0, + b: 0, + c: 1 ether + }); + + vm.prank(userTwo); + origPubId = hub.post( + DataTypes.PostData({ + profileId: userTwoProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + vm.prank(publisher); + pubId = hub.mirror( + DataTypes.MirrorData({ + profileId: publisherProfileId, + profileIdPointed: userTwoProfileId, + pubIdPointed: origPubId, + referenceModule: address(0), + referenceModuleInitData: '', + referenceModuleData: '' + }) + ); + + currency.mint(user, type(uint256).max); + vm.prank(user); + currency.approve(address(stepwiseCollectModule), type(uint256).max); + } + + function hubPost(StepwiseCollectModuleInitData memory initData) + public + override + returns (uint256) + { + vm.prank(userTwo); + origPubId = hub.post( + DataTypes.PostData({ + profileId: userTwoProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + vm.prank(publisher); + uint256 mirrorId = hub.mirror( + DataTypes.MirrorData({ + profileId: publisherProfileId, + profileIdPointed: userTwoProfileId, + pubIdPointed: origPubId, + referenceModule: address(0), + referenceModuleInitData: '', + referenceModuleData: '' + }) + ); + return mirrorId; + } + + function testCurrentCollectsIncreaseProperlyWhenCollecting() public override { + uint256 secondPubId = hubPost(exampleInitData); + vm.startPrank(user); + + ProfilePublicationData memory fetchedData = stepwiseCollectModule.getPublicationData( + userTwoProfileId, + origPubId + ); + assertEq(fetchedData.currentCollects, 0); + + for (uint256 collects = 1; collects < 5; collects++) { + hub.collect(publisherProfileId, secondPubId, abi.encode(address(currency), 1 ether)); + fetchedData = stepwiseCollectModule.getPublicationData(userTwoProfileId, origPubId); + assertEq(fetchedData.currentCollects, collects); + } + vm.stopPrank(); + } +} + +///////////// +// Fee Distribution +// +contract StepwiseCollectModule_FeeDistribution is StepwiseCollectModuleBase { + struct Balances { + uint256 treasury; + uint256 referral; + uint256 publisher; + uint256 user; + } + + uint16 internal constant BPS_MAX = 10000; + + uint256 immutable publisherProfileId; + uint256 immutable userProfileId; + uint256 immutable mirrorerProfileId; + + StepwiseCollectModuleInitData exampleInitData; + + constructor() StepwiseCollectModuleBase() { + publisherProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: publisher, + handle: 'pub', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + + userProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: user, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + + mirrorerProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: userTwo, + handle: 'usertwo.lens', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + } + + function setUp() public virtual { + exampleInitData = StepwiseCollectModuleInitData({ + collectLimit: 0, + currency: address(currency), + recipient: address(publisher), + referralFee: 0, + followerOnly: false, + endTimestamp: 0, + a: 0, + b: 0, + c: 1 ether + }); + + currency.mint(user, type(uint256).max); + vm.prank(user); + currency.approve(address(stepwiseCollectModule), type(uint256).max); + } + + function hubPostAndMirror( + StepwiseCollectModuleInitData memory initData, + uint16 referralFee, + uint128 amount + ) public returns (uint256, uint256) { + exampleInitData.referralFee = referralFee; + exampleInitData.c = amount; + vm.prank(publisher); + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + vm.prank(userTwo); + uint256 mirrorId = hub.mirror( + DataTypes.MirrorData({ + profileId: mirrorerProfileId, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + referenceModule: address(0), + referenceModuleInitData: '', + referenceModuleData: '' + }) + ); + return (pubId, mirrorId); + } + + function verifyFeesWithoutMirror(uint16 treasuryFee, uint128 amount) public { + vm.prank(governance); + moduleGlobals.setTreasuryFee(treasuryFee); + (uint256 pubId, ) = hubPostAndMirror(exampleInitData, 0, amount); + + Balances memory balancesBefore; + Balances memory balancesAfter; + Balances memory balancesChange; + + balancesBefore.treasury = currency.balanceOf(treasury); + balancesBefore.publisher = currency.balanceOf(publisher); + balancesBefore.user = currency.balanceOf(user); + + vm.prank(user); + vm.recordLogs(); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), amount)); + Vm.Log[] memory entries = vm.getRecordedLogs(); + + balancesAfter.treasury = currency.balanceOf(treasury); + balancesAfter.publisher = currency.balanceOf(publisher); + balancesAfter.user = currency.balanceOf(user); + + balancesChange.treasury = balancesAfter.treasury - balancesBefore.treasury; + balancesChange.publisher = balancesAfter.publisher - balancesBefore.publisher; + balancesChange.user = balancesBefore.user - balancesAfter.user; + + assertEq(balancesChange.treasury + balancesChange.publisher, balancesChange.user); + + uint256 treasuryAmount = (uint256(amount) * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = amount - treasuryAmount; + + assertEq(balancesChange.treasury, treasuryAmount); + assertEq(balancesChange.publisher, adjustedAmount); + assertEq(balancesChange.user, amount); + + if (amount == 0 || adjustedAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, publisher); + assertEq(balancesChange.treasury, 0); + assertEq(balancesChange.publisher, 0); + assertEq(balancesChange.user, 0); + } else { + uint256 ownerFeeTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + publisher + ); + assertEq(ownerFeeTransferEventAmount, adjustedAmount); + } + if (treasuryFee == 0 || treasuryAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, treasury); + assertEq(balancesChange.treasury, 0); + } else { + uint256 treasuryTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + treasury + ); + assertEq(treasuryTransferEventAmount, treasuryAmount); + } + } + + function verifyFeesWithMirror( + uint16 treasuryFee, + uint16 referralFee, + uint128 amount + ) public { + vm.prank(governance); + moduleGlobals.setTreasuryFee(treasuryFee); + (uint256 pubId, uint256 mirrorId) = hubPostAndMirror(exampleInitData, referralFee, amount); + + Vm.Log[] memory entries; + + Balances memory balancesBefore; + Balances memory balancesAfter; + Balances memory balancesChange; + + balancesBefore.treasury = currency.balanceOf(treasury); + balancesBefore.referral = currency.balanceOf(userTwo); + balancesBefore.publisher = currency.balanceOf(publisher); + balancesBefore.user = currency.balanceOf(user); + + vm.recordLogs(); + vm.prank(user); + hub.collect(mirrorerProfileId, mirrorId, abi.encode(address(currency), amount)); + entries = vm.getRecordedLogs(); + + balancesAfter.treasury = currency.balanceOf(treasury); + balancesAfter.referral = currency.balanceOf(userTwo); + balancesAfter.publisher = currency.balanceOf(publisher); + balancesAfter.user = currency.balanceOf(user); + + balancesChange.treasury = balancesAfter.treasury - balancesBefore.treasury; + balancesChange.referral = balancesAfter.referral - balancesBefore.referral; + balancesChange.publisher = balancesAfter.publisher - balancesBefore.publisher; + balancesChange.user = balancesBefore.user - balancesAfter.user; + + assertEq( + balancesChange.treasury + balancesChange.referral + balancesChange.publisher, + balancesChange.user + ); + + uint256 treasuryAmount = (uint256(amount) * treasuryFee) / BPS_MAX; + uint256 adjustedAmount = uint256(amount) - treasuryAmount; + uint256 referralAmount = (adjustedAmount * referralFee) / BPS_MAX; + + if (referralFee != 0) adjustedAmount = adjustedAmount - referralAmount; + + assertEq(balancesChange.treasury, treasuryAmount); + assertEq(balancesChange.referral, referralAmount); + assertEq(balancesChange.publisher, adjustedAmount); + assertEq(balancesChange.user, amount); + + if (amount == 0 || adjustedAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, publisher); + assertEq(balancesChange.treasury, 0); + assertEq(balancesChange.referral, 0); + assertEq(balancesChange.publisher, 0); + assertEq(balancesChange.user, 0); + } else { + uint256 ownerFeeTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + publisher + ); + assertEq(ownerFeeTransferEventAmount, adjustedAmount); + } + + if (treasuryFee == 0 || treasuryAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, treasury); + assertEq(balancesChange.treasury, 0); + } else { + uint256 treasuryTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + treasury + ); + assertEq(treasuryTransferEventAmount, treasuryAmount); + } + + if (referralFee == 0 || referralAmount == 0) { + vm.expectRevert('No Transfer event found'); + TestHelpers.getTransferFromEvents(entries, user, userTwo); + assertEq(balancesChange.referral, referralAmount); + } else { + uint256 referralTransferEventAmount = TestHelpers.getTransferFromEvents( + entries, + user, + userTwo + ); + assertEq(referralTransferEventAmount, referralAmount); + } + } + + function testFeesDistributionEdgeCasesWithoutMirror() public { + verifyFeesWithoutMirror(0, 0); + verifyFeesWithoutMirror(0, 1 ether); + verifyFeesWithoutMirror(0, type(uint128).max); + verifyFeesWithoutMirror(BPS_MAX / 2 - 1, 0); + verifyFeesWithoutMirror(BPS_MAX / 2 - 1, 1 ether); + verifyFeesWithoutMirror(BPS_MAX / 2 - 1, type(uint128).max); + } + + function testFeesDistributionWithoutMirrorFuzzing(uint16 treasuryFee, uint128 amount) public { + treasuryFee = uint16(bound(treasuryFee, 0, BPS_MAX / 2 - 2)); + + verifyFeesWithoutMirror(treasuryFee, amount); + } + + function testFeesDistributionEdgeCasesWithMirror() public { + verifyFeesWithMirror(0, 0, 0); + verifyFeesWithMirror(0, 0, type(uint128).max); + verifyFeesWithMirror(0, BPS_MAX / 2 - 1, 0); + verifyFeesWithMirror(0, BPS_MAX / 2 - 1, type(uint128).max); + verifyFeesWithMirror(BPS_MAX / 2 - 1, 0, 0); + verifyFeesWithMirror(BPS_MAX / 2 - 1, 0, type(uint128).max); + verifyFeesWithMirror(BPS_MAX / 2 - 1, BPS_MAX / 2 - 1, 0); + verifyFeesWithMirror(BPS_MAX / 2 - 1, BPS_MAX / 2 - 1, type(uint128).max); + verifyFeesWithMirror(0, 0, 1); + verifyFeesWithMirror(0, 1, 0); + verifyFeesWithMirror(0, 1, 1); + verifyFeesWithMirror(1, 0, 1); + verifyFeesWithMirror(1, 1, 0); + verifyFeesWithMirror(1, 1, 1); + } + + function testFeesDistributionWithMirrorFuzzing( + uint16 treasuryFee, + uint16 referralFee, + uint128 amount + ) public { + treasuryFee = uint16(bound(treasuryFee, 0, BPS_MAX / 2 - 2)); + referralFee = uint16(bound(referralFee, 0, BPS_MAX / 2 - 2)); + verifyFeesWithMirror(treasuryFee, referralFee, amount); + } +} + +///////////// +// Quadratic formula calculation +// +library Calculations { + function expectedStepwiseAmount( + StepwiseCollectModule stepwiseCollectModule, + uint256 a, + uint256 b, + uint256 c, + uint256 currentCollects + ) internal returns (uint256) { + return + ((uint256(a) * (uint256(currentCollects) * uint256(currentCollects))) / + stepwiseCollectModule.A_DECIMALS()) + + ((uint256(b) * uint256(currentCollects)) / stepwiseCollectModule.B_DECIMALS()) + + uint256(c); + } +} + +///////////// +// Stepwise curve formula +// +contract StepwiseCollectModule_StepwiseCurveFormula is StepwiseCollectModuleBase { + uint256 immutable publisherProfileId; + uint256 immutable userProfileId; + + StepwiseCollectModuleInitData exampleInitData; + + event Transfer(address indexed from, address indexed to, uint256 value); + + constructor() StepwiseCollectModuleBase() { + publisherProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: publisher, + handle: 'pub', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + + userProfileId = hub.createProfile( + DataTypes.CreateProfileData({ + to: user, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + + vm.prank(governance); + moduleGlobals.setTreasuryFee(0); + } + + function setUp() public virtual { + exampleInitData = StepwiseCollectModuleInitData({ + collectLimit: 0, + currency: address(currency), + recipient: address(publisher), + referralFee: 0, + followerOnly: false, + endTimestamp: 0, + a: 0, + b: 0, + c: 1 ether + }); + + currency.mint(user, type(uint256).max); + vm.prank(user); + currency.approve(address(stepwiseCollectModule), type(uint256).max); + } + + function testStepwiseCollectConstant() public { + exampleInitData.a = 0; + exampleInitData.b = 0; + exampleInitData.c = 1; + + vm.prank(publisher); + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + for (uint256 i = 0; i < 10; i++) { + uint256 expectedAmount = 1; + assertEq(stepwiseCollectModule.previewFee(publisherProfileId, pubId), expectedAmount); + vm.prank(user); + vm.expectEmit(true, true, true, true, address(currency)); + emit Transfer(user, publisher, expectedAmount); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), expectedAmount)); + } + } + + function testStepwiseCollectLinear() public { + exampleInitData.a = 0; + exampleInitData.b = uint56(2 * stepwiseCollectModule.B_DECIMALS()); + exampleInitData.c = 2; + + vm.prank(publisher); + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + console.log('Linear increase test (2, 4, 6, ...):'); + for (uint256 i = 0; i < 10; i++) { + uint256 expectedAmount = 2 + 2 * i; + assertEq(stepwiseCollectModule.previewFee(publisherProfileId, pubId), expectedAmount); + vm.prank(user); + vm.expectEmit(true, true, true, true, address(currency)); + emit Transfer(user, publisher, expectedAmount); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), expectedAmount)); + console.log(' ', expectedAmount); + } + } + + function testStepwiseCollectSquared() public { + exampleInitData.a = uint72(stepwiseCollectModule.A_DECIMALS()); + exampleInitData.b = 0; + exampleInitData.c = 0; + + vm.prank(publisher); + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + console.log('Squared curve test (0, 1, 4, 9, ...):'); + for (uint256 i = 0; i < 10; i++) { + uint256 expectedAmount = i * i; + assertEq(stepwiseCollectModule.previewFee(publisherProfileId, pubId), expectedAmount); + vm.prank(user); + if (expectedAmount != 0) { + vm.expectEmit(true, false, false, false); + emit Transfer(user, publisher, expectedAmount); + } + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), expectedAmount)); + console.log(' ', expectedAmount); + } + } + + function testStepwiseCollectFuzz( + uint72 a, + uint56 b, + uint128 c, + uint64 numberOfCollects + ) public { + console.log('Testing %s collects:', numberOfCollects); + numberOfCollects = uint64(bound(numberOfCollects, 1, 99)); + + exampleInitData.a = a; + exampleInitData.b = b; + exampleInitData.c = c; + + vm.prank(publisher); + uint256 pubId = hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: address(stepwiseCollectModule), + collectModuleInitData: abi.encode(exampleInitData), + referenceModule: address(0), + referenceModuleInitData: '' + }) + ); + + for (uint256 i = 0; i < numberOfCollects; i++) { + uint256 currentCollects = stepwiseCollectModule + .getPublicationData(publisherProfileId, pubId) + .currentCollects; + assertEq(currentCollects, i, 'Number of collects doesnt match'); + uint256 expectedAmount = Calculations.expectedStepwiseAmount( + stepwiseCollectModule, + a, + b, + c, + currentCollects + ); + assertEq(stepwiseCollectModule.previewFee(publisherProfileId, pubId), expectedAmount); + console.log(' ', expectedAmount); + vm.prank(user); + if (expectedAmount > 0) vm.expectEmit(true, true, true, true, address(currency)); + emit Transfer(user, publisher, expectedAmount); + hub.collect(publisherProfileId, pubId, abi.encode(address(currency), expectedAmount)); + } + } +} + +///////////// +// CalculateFee function +// +contract StepwiseCollectModule_StepwiseCalculateFeeInternal is StepwiseCollectModule, Test { + constructor() StepwiseCollectModule(address(1), address(2)) {} + + function testCalculateFeeMax() public { + ProfilePublicationData memory testData; + testData.a = type(uint72).max; + testData.b = type(uint56).max; + testData.c = type(uint128).max; + testData.currentCollects = type(uint64).max; + + uint256 amount = StepwiseCollectModule._calculateFee(testData); + + uint256 expectedAmount = Calculations.expectedStepwiseAmount( + this, + testData.a, + testData.b, + testData.c, + testData.currentCollects - 1 + ); + + assertEq(amount, expectedAmount); + } + + function testCalculateFeeFuzz( + uint72 a, + uint56 b, + uint128 c, + uint64 currentCollects + ) public { + currentCollects = uint64(bound(currentCollects, 1, type(uint64).max)); + ProfilePublicationData memory testData; + testData.a = a; + testData.b = b; + testData.c = c; + testData.currentCollects = currentCollects; + + uint256 amount = StepwiseCollectModule._calculateFee(testData); + + uint256 expectedAmount = Calculations.expectedStepwiseAmount( + this, + a, + b, + c, + currentCollects - 1 + ); + + assertEq(amount, expectedAmount); + } +} diff --git a/lens-protocol/modules/test/foundry/helpers/TestHelpers.sol b/lens-protocol/modules/test/foundry/helpers/TestHelpers.sol new file mode 100644 index 0000000..8ab9dd8 --- /dev/null +++ b/lens-protocol/modules/test/foundry/helpers/TestHelpers.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import {Vm} from 'forge-std/Test.sol'; + +library TestHelpers { + // TODO: Replace these constants with Events.***.selector after upping to Solidity >=0.8.15 + bytes32 constant profileCreatedEventTopic = + keccak256( + 'ProfileCreated(uint256,address,address,string,string,address,bytes,string,uint256)' + ); + + bytes32 constant postCreatedEventTopic = + keccak256('PostCreated(uint256,uint256,string,address,bytes,address,bytes,uint256)'); + + bytes32 constant mirrorCreatedEventTopic = + keccak256('MirrorCreated(uint256,uint256,uint256,uint256,bytes,address,bytes,uint256)'); + + bytes32 constant transferEventTopic = keccak256('Transfer(address,address,uint256)'); + + function getCreatedProfileIdFromEvents(Vm.Log[] memory entries) public pure returns (uint256) { + for (uint256 i = 0; i < entries.length; i++) { + if (entries[i].topics[0] == profileCreatedEventTopic) { + return uint256(entries[i].topics[1]); // 0 is always event topic + } + } + revert('No Profile creation event found'); + } + + function getCreatedPubIdFromEvents(Vm.Log[] memory entries) public pure returns (uint256) { + for (uint256 i = 0; i < entries.length; i++) { + if (entries[i].topics[0] == postCreatedEventTopic) { + return uint256(entries[i].topics[2]); // 0 is always event topic + } + } + revert('No Publication creation event found'); + } + + function getCreatedMirrorIdFromEvents(Vm.Log[] memory entries) public pure returns (uint256) { + for (uint256 i = 0; i < entries.length; i++) { + if (entries[i].topics[0] == mirrorCreatedEventTopic) { + return uint256(entries[i].topics[2]); // 0 is always event topic + } + } + revert('No Mirror creation event found'); + } + + function getTransferFromEvents( + Vm.Log[] memory entries, + address from, + address to + ) public pure returns (uint256) { + for (uint256 i = 0; i < entries.length; i++) { + if (entries[i].topics[0] == transferEventTopic) { + if ( + entries[i].topics[1] == bytes32(abi.encode(from)) && + entries[i].topics[2] == bytes32(abi.encode(to)) + ) { + return abi.decode(entries[i].data, (uint256)); // 0 is always event topic + } + } + } + revert('No Transfer event found'); + } +} diff --git a/lens-protocol/modules/test/foundry/reference/TokenGatedReferenceModule.base.sol b/lens-protocol/modules/test/foundry/reference/TokenGatedReferenceModule.base.sol new file mode 100644 index 0000000..7716db6 --- /dev/null +++ b/lens-protocol/modules/test/foundry/reference/TokenGatedReferenceModule.base.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import 'forge-std/Test.sol'; +import '../BaseSetup.t.sol'; +import 'contracts/reference/TokenGatedReferenceModule.sol'; + +// import '../helpers/TestHelpers.sol'; + +contract TokenGatedReferenceModuleBase is BaseSetup { + using stdJson for string; + TokenGatedReferenceModule tokenGatedReferenceModule; + + // Deploy & Whitelist TokenGatedReferenceModule + constructor() BaseSetup() { + if ( + fork && keyExists(string(abi.encodePacked('.', forkEnv, '.TokenGatedReferenceModule'))) + ) { + tokenGatedReferenceModule = TokenGatedReferenceModule( + json.readAddress( + string(abi.encodePacked('.', forkEnv, '.TokenGatedReferenceModule')) + ) + ); + console.log( + 'Testing against already deployed module at:', + address(tokenGatedReferenceModule) + ); + } else { + vm.prank(deployer); + tokenGatedReferenceModule = new TokenGatedReferenceModule(hubProxyAddr); + } + vm.prank(governance); + hub.whitelistReferenceModule(address(tokenGatedReferenceModule), true); + } +} diff --git a/lens-protocol/modules/test/foundry/reference/TokenGatedReferenceModule.test.sol b/lens-protocol/modules/test/foundry/reference/TokenGatedReferenceModule.test.sol new file mode 100644 index 0000000..c4234d6 --- /dev/null +++ b/lens-protocol/modules/test/foundry/reference/TokenGatedReferenceModule.test.sol @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import '../BaseSetup.t.sol'; +import {TokenGatedReferenceModuleBase} from './TokenGatedReferenceModule.base.sol'; +import '../helpers/TestHelpers.sol'; +import {TokenGatedReferenceModule} from 'contracts/reference/TokenGatedReferenceModule.sol'; + +///////// +// Publication Creation with TokenGatedReferenceModule +// +contract TokenGatedReferenceModule_Publication is TokenGatedReferenceModuleBase { + uint256 immutable userProfileId; + + constructor() TokenGatedReferenceModuleBase() { + vm.recordLogs(); + hub.createProfile( + DataTypes.CreateProfileData({ + to: me, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + Vm.Log[] memory entries = vm.getRecordedLogs(); + userProfileId = TestHelpers.getCreatedProfileIdFromEvents(entries); + } + + // Negatives + function testCannotPostWithZeroTokenAddress() public { + vm.expectRevert(Errors.InitParamsInvalid.selector); + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: abi.encode(address(0), 1) + }) + ); + } + + function testCannotPostWithZeroMinThreshold() public { + vm.expectRevert(Errors.InitParamsInvalid.selector); + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: abi.encode(address(currency), 0) + }) + ); + } + + function testCannotCallInitializeFromNonHub() public { + vm.expectRevert(Errors.NotHub.selector); + tokenGatedReferenceModule.initializeReferenceModule( + userProfileId, + 1, + abi.encode(address(currency), 1) + ); + } + + function testCannotProcessCommentFromNonHub() public { + vm.expectRevert(Errors.NotHub.selector); + tokenGatedReferenceModule.processComment(userProfileId, userProfileId, 1, ''); + } + + function testCannotProcessMirrorFromNonHub() public { + vm.expectRevert(Errors.NotHub.selector); + tokenGatedReferenceModule.processMirror(userProfileId, userProfileId, 1, ''); + } + + // Scenarios + function testCreatePublicationWithTokenGatedReferenceModule() public { + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: abi.encode(address(currency), 1) + }) + ); + } + + function testCreatePublicationWithTokenGatedReferenceModuleEmitsExpectedEvents() public { + vm.recordLogs(); + hub.post( + DataTypes.PostData({ + profileId: userProfileId, + contentURI: MOCK_URI, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: abi.encode(address(currency), 1) + }) + ); + Vm.Log[] memory entries = vm.getRecordedLogs(); + uint256 pubId = TestHelpers.getCreatedPubIdFromEvents(entries); + assertEq(pubId, 1); + } +} + +///////// +// ERC20-Gated Reference +// +contract TokenGatedReferenceModule_ERC20_Gated is TokenGatedReferenceModuleBase { + uint256 immutable publisherProfileId; + uint256 immutable userProfileId; + + address immutable tokenAddress; + uint256 constant minThreshold = 10 ether; + + bytes referenceModuleInitData; + + uint256 pubId; + + constructor() TokenGatedReferenceModuleBase() { + vm.recordLogs(); + hub.createProfile( + DataTypes.CreateProfileData({ + to: publisher, + handle: MOCK_HANDLE, + imageURI: MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_URI + }) + ); + Vm.Log[] memory entries = vm.getRecordedLogs(); + publisherProfileId = TestHelpers.getCreatedProfileIdFromEvents(entries); + vm.recordLogs(); + hub.createProfile( + DataTypes.CreateProfileData({ + to: me, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + entries = vm.getRecordedLogs(); + userProfileId = TestHelpers.getCreatedProfileIdFromEvents(entries); + + tokenAddress = address(currency); + referenceModuleInitData = abi.encode(tokenAddress, minThreshold); + } + + function setUp() public { + vm.recordLogs(); + vm.prank(publisher); + hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + Vm.Log[] memory entries = vm.getRecordedLogs(); + pubId = TestHelpers.getCreatedPubIdFromEvents(entries); + } + + // Negatives + function testCannotMirrorIfNotEnoughBalance() public { + vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector); + hub.mirror( + DataTypes.MirrorData({ + profileId: userProfileId, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + referenceModuleData: '', + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + } + + function testCannotCommentIfNotEnoughBalance() public { + vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector); + hub.comment( + DataTypes.CommentData({ + profileId: userProfileId, + contentURI: MOCK_URI, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModuleData: '', + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + } + + // Scenarios + function testMirrorWhileHoldingEnoughTokens() public { + currency.mint(me, minThreshold); + assert(currency.balanceOf(me) >= minThreshold); + hub.mirror( + DataTypes.MirrorData({ + profileId: userProfileId, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + referenceModuleData: '', + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + } + + function testCommentWhileHoldingEnoughTokens() public { + currency.mint(me, minThreshold); + assert(currency.balanceOf(me) >= minThreshold); + hub.comment( + DataTypes.CommentData({ + profileId: userProfileId, + contentURI: MOCK_URI, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModuleData: '', + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + } +} + +///////// +// ERC721-Gated Reference +// +contract TokenGatedReferenceModule_ERC721_Gated is TokenGatedReferenceModuleBase { + uint256 immutable publisherProfileId; + uint256 immutable userProfileId; + + address immutable tokenAddress; + uint256 constant minThreshold = 1; + + bytes referenceModuleInitData; + + uint256 pubId; + + constructor() TokenGatedReferenceModuleBase() { + vm.recordLogs(); + hub.createProfile( + DataTypes.CreateProfileData({ + to: publisher, + handle: MOCK_HANDLE, + imageURI: MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_URI + }) + ); + Vm.Log[] memory entries = vm.getRecordedLogs(); + publisherProfileId = TestHelpers.getCreatedProfileIdFromEvents(entries); + vm.recordLogs(); + hub.createProfile( + DataTypes.CreateProfileData({ + to: me, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: address(0), + followModuleInitData: '', + followNFTURI: MOCK_FOLLOW_NFT_URI + }) + ); + entries = vm.getRecordedLogs(); + userProfileId = TestHelpers.getCreatedProfileIdFromEvents(entries); + + tokenAddress = address(nft); + referenceModuleInitData = abi.encode(tokenAddress, minThreshold); + } + + function setUp() public { + vm.recordLogs(); + vm.prank(publisher); + hub.post( + DataTypes.PostData({ + profileId: publisherProfileId, + contentURI: MOCK_URI, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + Vm.Log[] memory entries = vm.getRecordedLogs(); + pubId = TestHelpers.getCreatedPubIdFromEvents(entries); + console.log('post created:', pubId); + } + + // Negatives + function testCannotMirrorIfNotEnoughBalance() public { + vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector); + hub.mirror( + DataTypes.MirrorData({ + profileId: userProfileId, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + referenceModuleData: '', + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + } + + function testCannotCommentIfNotEnoughBalance() public { + vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector); + hub.comment( + DataTypes.CommentData({ + profileId: userProfileId, + contentURI: MOCK_URI, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModuleData: '', + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + } + + // Scenarios + function testMirrorWhileHoldingEnoughTokens() public { + nft.mint(me, 1); + assert(nft.balanceOf(me) >= minThreshold); + hub.mirror( + DataTypes.MirrorData({ + profileId: userProfileId, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + referenceModuleData: '', + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + } + + function testCommentWhileHoldingEnoughTokens() public { + nft.mint(me, 1); + assert(nft.balanceOf(me) >= minThreshold); + hub.comment( + DataTypes.CommentData({ + profileId: userProfileId, + contentURI: MOCK_URI, + profileIdPointed: publisherProfileId, + pubIdPointed: pubId, + collectModule: address(freeCollectModule), + collectModuleInitData: abi.encode(false), + referenceModuleData: '', + referenceModule: address(tokenGatedReferenceModule), + referenceModuleInitData: referenceModuleInitData + }) + ); + } +} diff --git a/lens-protocol/modules/test/helpers/constants.ts b/lens-protocol/modules/test/helpers/constants.ts new file mode 100644 index 0000000..c0dd957 --- /dev/null +++ b/lens-protocol/modules/test/helpers/constants.ts @@ -0,0 +1,18 @@ +export const MAX_UINT256 = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'; +export const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; +export const ONE_DAY = 86400; +export const POOL_ADDRESSES_PROVIDER_ADDRESS = '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb'; +export const POOL_ADDRESS = '0x794a61358D6845594F94dc1DB02A252b5b4814aD'; + +// Fetched from $npx hardhat node, account # 7 +export const FAKE_PRIVATEKEY = '0xa2e0097c961c67ec197b6865d7ecea6caffc68ebeb00e6050368c8f67fc9c588'; + +export const HARDHAT_CHAINID = 31337; + +export enum PubType { + Post, + Comment, + Mirror, + Nonexistent, +} diff --git a/lens-protocol/modules/test/helpers/errors.ts b/lens-protocol/modules/test/helpers/errors.ts new file mode 100644 index 0000000..b308d60 --- /dev/null +++ b/lens-protocol/modules/test/helpers/errors.ts @@ -0,0 +1,69 @@ +export const ERRORS = { + // TokenGatedReferenceModule + NOT_ENOUGH_BALANCE: 'NotEnoughBalance()', + + // AuctionCollectModule + ONGOING_AUCTION: 'OngoingAuction()', + UNAVAILABLE_AUCTION: 'UnavailableAuction()', + COLLECT_ALREADY_PROCESSED: 'CollectAlreadyProcessed()', + FEE_ALREADY_PROCESSED: 'FeeAlreadyProcessed()', + INSUFFICIENT_BID_AMOUNT: 'InsufficientBidAmount()', + + // UpdatableOwnableFeeCollectModule + ONLY_OWNER: 'OnlyOwner()', + INVALID_PARAMETERS: 'InvalidParameters()', + + // DegreesOfSeparationReferenceModule + INVALID_DEGREES_OF_SEPARATION: 'InvalidDegreesOfSeparation()', + OPERATION_DISABLED: 'OperationDisabled()', + PROFILE_PATH_EXCEEDS_DEGREES_OF_SEPARATION: 'ProfilePathExceedsDegreesOfSeparation()', + PUBLICATION_NOT_SET_UP: 'PublicationNotSetUp()', + + // Core + CANNOT_INIT_IMPL: 'CannotInitImplementation()', + INITIALIZED: 'Initialized()', + SIGNATURE_EXPIRED: 'SignatureExpired()', + ZERO_SPENDER: 'ZeroSpender()', + SIGNATURE_INVALID: 'SignatureInvalid()', + NOT_OWNER_OR_APPROVED: 'NotOwnerOrApproved()', + NOT_HUB: 'NotHub()', + TOKEN_DOES_NOT_EXIST: 'TokenDoesNotExist()', + CALLER_NOT_WHITELSITED_MODULE: 'CallerNotWhitelistedModule()', + NOT_GOVERNANCE: 'NotGovernance()', + COLLECT_MODULE_NOT_WHITELISTED: 'CollectModuleNotWhitelisted()', + FOLLOW_MODULE_NOT_WHITELISTED: 'FollowModuleNotWhitelisted()', + REFERENCE_MODULE_NOT_WHITELISTED: 'ReferenceModuleNotWhitelisted()', + PROFILE_CREATOR_NOT_WHITELISTED: 'ProfileCreatorNotWhitelisted()', + NOT_PROFILE_OWNER: 'NotProfileOwner()', + NOT_PROFILE_OWNER_OR_DISPATCHER: 'NotProfileOwnerOrDispatcher()', + PUBLICATION_DOES_NOT_EXIST: 'PublicationDoesNotExist()', + PROFILE_HANDLE_TAKEN: 'HandleTaken()', + INVALID_HANDLE_LENGTH: 'HandleLengthInvalid()', + HANDLE_CONTAINS_INVALID_CHARACTERS: 'HandleContainsInvalidCharacters()', + NOT_FOLLOW_NFT: 'CallerNotFollowNFT()', + NOT_COLLECT_NFT: 'CallerNotCollectNFT()', + BLOCK_NUMBER_INVALID: 'BlockNumberInvalid()', + INIT_PARAMS_INVALID: 'InitParamsInvalid()', + ZERO_CURRENCY: 'ZeroCurrency()', + COLLECT_EXPIRED: 'CollectExpired()', + COLLECT_NOT_ALLOWED: 'CollectNotAllowed()', + MINT_LIMIT_EXCEEDED: 'MintLimitExceeded()', + FOLLOW_INVALID: 'FollowInvalid()', + MODULE_DATA_MISMATCH: 'ModuleDataMismatch()', + FOLLOW_NOT_APPROVED: 'FollowNotApproved()', + ARRAY_MISMATCH: 'ArrayMismatch()', + ERC721_NOT_OWN: 'ERC721: transfer of token that is not own', + ERC721_TRANSFER_NOT_OWNER_OR_APPROVED: 'ERC721: transfer caller is not owner nor approved', + ERC721_QUERY_FOR_NONEXISTENT_TOKEN: 'ERC721: owner query for nonexistent token', + ERC721_MINT_TO_ZERO_ADDRESS: 'ERC721: mint to the zero address', + ERC20_TRANSFER_EXCEEDS_ALLOWANCE: 'ERC20: transfer amount exceeds allowance', + ERC20_INSUFFICIENT_ALLOWANCE: 'ERC20: insufficient allowance', + ERC20_TRANSFER_EXCEEDS_BALANCE: 'ERC20: transfer amount exceeds balance', + NO_SELECTOR: + "Transaction reverted: function selector was not recognized and there's no fallback function", + PAUSED: 'Paused()', + PUBLISHING_PAUSED: 'PublishingPaused()', + NOT_GOVERNANCE_OR_EMERGENCY_ADMIN: 'NotGovernanceOrEmergencyAdmin()', + NO_REASON_ABI_DECODE: + "Transaction reverted and Hardhat couldn't infer the reason. Please report this to help us improve Hardhat.", +}; diff --git a/lens-protocol/modules/test/helpers/signatures/modules/collect/auction-collect-module.ts b/lens-protocol/modules/test/helpers/signatures/modules/collect/auction-collect-module.ts new file mode 100644 index 0000000..5569871 --- /dev/null +++ b/lens-protocol/modules/test/helpers/signatures/modules/collect/auction-collect-module.ts @@ -0,0 +1,80 @@ +// File based on https://github.com/dmihal/eth-permit/blob/master/src/eth-permit.ts, modified for other EIP-712 message + +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { BigNumberish } from 'ethers'; +import { ethers } from 'hardhat'; +import { AuctionCollectModule__factory } from '../../../../../typechain'; +import { BID_WITH_SIG_DOMAIN } from '../../../../modules/collect/auction-collect-module.spec'; +import { DEFAULT_AMOUNT, FIRST_PROFILE_ID, FIRST_PUB_ID } from '../../../../__setup.spec'; +import { Domain, EIP712Domain, RSV, signData, toStringOrNumber } from '../../utils'; + +interface BidWithSigMessage { + profileId: number | string; + pubId: number | string; + amount: number | string; + followNftTokenId: number | string; + nonce: number | string; + deadline: number | string; +} + +const createTypedData = (message: BidWithSigMessage, domain: Domain) => { + const typedData = { + types: { + EIP712Domain, + BidWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'pubId', type: 'uint256' }, + { name: 'amount', type: 'uint256' }, + { name: 'followNftTokenId', type: 'uint256' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + primaryType: 'BidWithSig', + domain, + message, + }; + + return typedData; +}; + +interface SignBidWithSigMessageData { + signer: SignerWithAddress; + domain?: Domain; + profileId?: BigNumberish; + pubId?: BigNumberish; + amount?: BigNumberish; + followNftTokenId?: BigNumberish; + nonce?: BigNumberish; + deadline?: BigNumberish; +} + +export async function signBidWithSigMessage({ + signer, + domain = BID_WITH_SIG_DOMAIN, + profileId = FIRST_PROFILE_ID, + pubId = FIRST_PUB_ID, + amount = DEFAULT_AMOUNT, + followNftTokenId = 0, + nonce, + deadline = ethers.constants.MaxUint256, +}: SignBidWithSigMessageData): Promise { + const message: BidWithSigMessage = { + profileId: toStringOrNumber(profileId), + pubId: toStringOrNumber(pubId), + amount: toStringOrNumber(amount), + followNftTokenId: toStringOrNumber(followNftTokenId), + nonce: toStringOrNumber( + nonce || + (await new AuctionCollectModule__factory(signer) + .attach(domain.verifyingContract) + .nonces(signer.address)) + ), + deadline: toStringOrNumber(deadline), + }; + + const typedData = createTypedData(message, domain); + const sig = await signData(signer.provider, signer.address, typedData); + + return { ...sig, ...message }; +} diff --git a/lens-protocol/modules/test/helpers/signatures/modules/collect/updatable-ownable-fee-collect-module.ts b/lens-protocol/modules/test/helpers/signatures/modules/collect/updatable-ownable-fee-collect-module.ts new file mode 100644 index 0000000..f27c095 --- /dev/null +++ b/lens-protocol/modules/test/helpers/signatures/modules/collect/updatable-ownable-fee-collect-module.ts @@ -0,0 +1,104 @@ +// File based on https://github.com/dmihal/eth-permit/blob/master/src/eth-permit.ts, modified for other EIP-712 message + +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { BigNumberish } from 'ethers'; +import { ethers } from 'hardhat'; +import { UpdatableOwnableFeeCollectModule__factory } from '../../../../../typechain'; +import { UPDATE_MODULE_PARAMETERS_WITH_SIG_DOMAIN } from '../../../../modules/collect/updatable-ownable-fee-collect-module.spec'; +import { + currency, + DEFAULT_AMOUNT, + feeRecipient, + FIRST_PROFILE_ID, + FIRST_PUB_ID, + REFERRAL_FEE_BPS, +} from '../../../../__setup.spec'; +import { Domain, EIP712Domain, RSV, signData, toStringOrNumber } from '../../utils'; + +interface UpdateModuleParametersWithSigMessage { + profileId: number | string; + pubId: number | string; + amount: number | string; + currency: string; + recipient: string; + referralFee: number | string; + followerOnly: boolean; + nonce: number | string; + deadline: number | string; +} + +const createTypedData = (message: UpdateModuleParametersWithSigMessage, domain: Domain) => { + const typedData = { + types: { + EIP712Domain, + UpdateModuleParametersWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'pubId', type: 'uint256' }, + { name: 'amount', type: 'uint256' }, + { name: 'currency', type: 'address' }, + { name: 'recipient', type: 'address' }, + { name: 'referralFee', type: 'uint16' }, + { name: 'followerOnly', type: 'bool' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + primaryType: 'UpdateModuleParametersWithSig', + domain, + message, + }; + + return typedData; +}; + +interface SignUpdateModuleParametersWithSigMessageData { + signer: SignerWithAddress; + domain?: Domain; + profileId?: BigNumberish; + pubId?: BigNumberish; + amount?: BigNumberish; + feeCurrency?: string; + recipient?: string; + referralFee?: BigNumberish; + followerOnly?: boolean; + nonce?: BigNumberish; + deadline?: BigNumberish; +} + +export async function signUpdateModuleParametersWithSigMessage({ + signer, + domain = UPDATE_MODULE_PARAMETERS_WITH_SIG_DOMAIN, + profileId = FIRST_PROFILE_ID, + pubId = FIRST_PUB_ID, + amount = DEFAULT_AMOUNT, + feeCurrency = currency.address, + recipient = feeRecipient.address, + referralFee = REFERRAL_FEE_BPS, + followerOnly = false, + nonce, + deadline = ethers.constants.MaxUint256, +}: SignUpdateModuleParametersWithSigMessageData): Promise< + UpdateModuleParametersWithSigMessage & RSV +> { + const message: UpdateModuleParametersWithSigMessage = { + profileId: toStringOrNumber(profileId), + pubId: toStringOrNumber(pubId), + amount: toStringOrNumber(amount), + currency: feeCurrency, + recipient: recipient, + referralFee: toStringOrNumber(referralFee), + followerOnly: followerOnly, + nonce: toStringOrNumber( + nonce || + (await new UpdatableOwnableFeeCollectModule__factory(signer) + .attach(domain.verifyingContract) + .sigNonces(signer.address)) + ), + deadline: toStringOrNumber(deadline), + }; + + const typedData = createTypedData(message, domain); + const sig = await signData(signer.provider, signer.address, typedData); + + return { ...sig, ...message }; +} diff --git a/lens-protocol/modules/test/helpers/signatures/modules/reference/degrees-of-separation-reference-module.ts b/lens-protocol/modules/test/helpers/signatures/modules/reference/degrees-of-separation-reference-module.ts new file mode 100644 index 0000000..306b423 --- /dev/null +++ b/lens-protocol/modules/test/helpers/signatures/modules/reference/degrees-of-separation-reference-module.ts @@ -0,0 +1,90 @@ +// File based on https://github.com/dmihal/eth-permit/blob/master/src/eth-permit.ts, modified for other EIP-712 message + +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { BigNumberish } from 'ethers'; +import { ethers } from 'hardhat'; +import { DegreesOfSeparationReferenceModule__factory } from '../../../../../typechain'; +import { + DEFAULT_DEGREES_OF_SEPARATION, + UPDATE_MODULE_PARAMETERS_WITH_SIG_DOMAIN, +} from '../../../../modules/reference/degrees-of-separation-reference-module.spec'; +import { FIRST_PROFILE_ID, FIRST_PUB_ID } from '../../../../__setup.spec'; +import { Domain, EIP712Domain, RSV, signData, toStringOrNumber } from '../../utils'; + +interface UpdateModuleParametersWithSigMessage { + profileId: number | string; + pubId: number | string; + commentsRestricted: boolean; + mirrorsRestricted: boolean; + degreesOfSeparation: number; + nonce: number | string; + deadline: number | string; +} + +const createTypedData = (message: UpdateModuleParametersWithSigMessage, domain: Domain) => { + const typedData = { + types: { + EIP712Domain, + UpdateModuleParametersWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'pubId', type: 'uint256' }, + { name: 'commentsRestricted', type: 'bool' }, + { name: 'mirrorsRestricted', type: 'bool' }, + { name: 'degreesOfSeparation', type: 'uint8' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + primaryType: 'UpdateModuleParametersWithSig', + domain, + message, + }; + + return typedData; +}; + +interface SignUpdateModuleParametersWithSigMessageData { + signer: SignerWithAddress; + domain?: Domain; + profileId?: BigNumberish; + pubId?: BigNumberish; + commentsRestricted?: boolean; + mirrorsRestricted?: boolean; + degreesOfSeparation?: number; + nonce?: BigNumberish; + deadline?: BigNumberish; +} + +export async function signUpdateModuleParametersWithSigMessage({ + signer, + domain = UPDATE_MODULE_PARAMETERS_WITH_SIG_DOMAIN, + profileId = FIRST_PROFILE_ID, + pubId = FIRST_PUB_ID, + commentsRestricted = true, + mirrorsRestricted = true, + degreesOfSeparation = DEFAULT_DEGREES_OF_SEPARATION, + nonce, + deadline = ethers.constants.MaxUint256, +}: SignUpdateModuleParametersWithSigMessageData): Promise< + UpdateModuleParametersWithSigMessage & RSV +> { + const message: UpdateModuleParametersWithSigMessage = { + profileId: toStringOrNumber(profileId), + pubId: toStringOrNumber(pubId), + commentsRestricted: commentsRestricted, + mirrorsRestricted: mirrorsRestricted, + degreesOfSeparation: degreesOfSeparation, + nonce: toStringOrNumber( + nonce || + (await new DegreesOfSeparationReferenceModule__factory(signer) + .attach(domain.verifyingContract) + .nonces(signer.address)) + ), + deadline: toStringOrNumber(deadline), + }; + + const typedData = createTypedData(message, domain); + const sig = await signData(signer.provider, signer.address, typedData); + + return { ...sig, ...message }; +} diff --git a/lens-protocol/modules/test/helpers/signatures/utils.ts b/lens-protocol/modules/test/helpers/signatures/utils.ts new file mode 100644 index 0000000..d1d7692 --- /dev/null +++ b/lens-protocol/modules/test/helpers/signatures/utils.ts @@ -0,0 +1,131 @@ +// Most of code taken from https://github.com/dmihal/eth-permit repository + +import { BigNumber, BigNumberish } from '@ethersproject/bignumber'; + +export function toStringOrNumber(bigNumberish: BigNumberish): string | number { + if (BigNumber.isBigNumber(bigNumberish)) { + return bigNumberish.toString(); + } else if (bigNumberish instanceof String) { + return bigNumberish as string; + } else if (bigNumberish instanceof Number) { + return bigNumberish as number; + } else { + return BigNumber.from(bigNumberish).toString(); + } +} + +export interface Domain { + name: string; + version: string; + chainId: number; + verifyingContract: string; +} + +export const EIP712Domain = [ + { name: 'name', type: 'string' }, + { name: 'version', type: 'string' }, + { name: 'chainId', type: 'uint256' }, + { name: 'verifyingContract', type: 'address' }, +]; + +const randomId = () => Math.floor(Math.random() * 10000000000); + +export const send = (provider: any, method: string, params?: any[]) => + new Promise((resolve, reject) => { + const payload = { + id: randomId(), + method, + params, + }; + const callback = (err: any, result: any) => { + if (err) { + reject(err); + } else if (result.error) { + console.error(result.error); + reject(result.error); + } else { + resolve(result.result); + } + }; + + const _provider = provider.provider?.provider || provider.provider || provider; + + if (_provider.getUncheckedSigner /* ethers provider */) { + _provider + .send(method, params) + .then((r: any) => resolve(r)) + .catch((e: any) => reject(e)); + } else if (_provider.sendAsync) { + _provider.sendAsync(payload, callback); + } else { + _provider.send(payload, callback).catch((error: any) => { + if (error.message === "Hardhat Network doesn't support JSON-RPC params sent as an object") { + _provider + .send(method, params) + .then((r: any) => resolve(r)) + .catch((e: any) => reject(e)); + } else { + throw error; + } + }); + } + }); + +export interface RSV { + r: string; + s: string; + v: number; +} + +const splitSignatureToRSV = (signature: string): RSV => { + const r = '0x' + signature.substring(2).substring(0, 64); + const s = '0x' + signature.substring(2).substring(64, 128); + const v = parseInt(signature.substring(2).substring(128, 130), 16); + return { r, s, v }; +}; + +const signWithEthers = async (signer: any, fromAddress: string, typeData: any): Promise => { + const signerAddress = await signer.getAddress(); + if (signerAddress.toLowerCase() !== fromAddress.toLowerCase()) { + throw new Error('Signer address does not match requested signing address'); + } + + const { EIP712Domain: _unused, ...types } = typeData.types; + const rawSignature = await (signer.signTypedData + ? signer.signTypedData(typeData.domain, types, typeData.message) + : signer._signTypedData(typeData.domain, types, typeData.message)); + + return splitSignatureToRSV(rawSignature); +}; + +export const signData = async (provider: any, fromAddress: string, typeData: any): Promise => { + if (provider._signTypedData || provider.signTypedData) { + return signWithEthers(provider, fromAddress, typeData); + } + + const typeDataString = typeof typeData === 'string' ? typeData : JSON.stringify(typeData); + const result = await send(provider, 'eth_signTypedData_v4', [fromAddress, typeDataString]).catch( + (error: any) => { + if (error.message === 'Method eth_signTypedData_v4 not supported.') { + return send(provider, 'eth_signTypedData', [fromAddress, typeData]); + } else { + throw error; + } + } + ); + + return { + r: result.slice(0, 66), + s: '0x' + result.slice(66, 130), + v: parseInt(result.slice(130, 132), 16), + }; +}; + +let chainIdOverride: null | number = null; + +export const setChainIdOverride = (id: number) => { + chainIdOverride = id; +}; + +export const getChainId = async (provider: any): Promise => + chainIdOverride || send(provider, 'eth_chainId'); diff --git a/lens-protocol/modules/test/helpers/utils.ts b/lens-protocol/modules/test/helpers/utils.ts new file mode 100644 index 0000000..e3059b7 --- /dev/null +++ b/lens-protocol/modules/test/helpers/utils.ts @@ -0,0 +1,812 @@ +import { TransactionReceipt, TransactionResponse } from '@ethersproject/providers'; +import { expect } from 'chai'; +import { BigNumber, BigNumberish, Bytes, Contract, logger, utils } from 'ethers'; +import { hexlify, keccak256, RLP, toUtf8Bytes } from 'ethers/lib/utils'; +import hre from 'hardhat'; +import { eventsLib, lensHub, LENS_HUB_NFT_NAME } from '../__setup.spec'; +import { HARDHAT_CHAINID } from './constants'; + +export enum ProtocolState { + Unpaused, + PublishingPaused, + Paused, +} + +export function matchEvent( + receipt: TransactionReceipt, + name: string, + expectedArgs?: any[], + eventContract: Contract = eventsLib +) { + const events = receipt.logs; + + if (events != undefined) { + // match name from list of events in eventContract, when found, compute the sigHash + let sigHash: string | undefined; + for (let contractEvents of Object.keys(eventContract.interface.events)) { + if (contractEvents.startsWith(name) && contractEvents.charAt(name.length) == '(') { + sigHash = keccak256(toUtf8Bytes(contractEvents)); + break; + } + } + // Throw if the sigHash was not found + if (!sigHash) { + logger.throwError( + `Event "${name}" not found in provided contract (default: Events libary). \nAre you sure you're using the right contract?` + ); + } + + // Find the given event in the emitted logs + let invalidParamsButExists = false; + for (let emittedEvent of events) { + // If we find one with the correct sighash, check if it is the one we're looking for + if (emittedEvent.topics[0] == sigHash) { + const event = eventContract.interface.parseLog(emittedEvent); + // If there are expected arguments, validate them, otherwise, return here + if (expectedArgs) { + if (expectedArgs.length != event.args.length) { + logger.throwError( + `Event "${name}" emitted with correct signature, but expected args are of invalid length` + ); + } + invalidParamsButExists = false; + // Iterate through arguments and check them, if there is a mismatch, continue with the loop + for (let i = 0; i < expectedArgs.length; i++) { + // Parse empty arrays as empty bytes + if (expectedArgs[i].constructor == Array && expectedArgs[i].length == 0) { + expectedArgs[i] = '0x'; + } + + // Break out of the expected args loop if there is a mismatch, this will continue the emitted event loop + if (BigNumber.isBigNumber(event.args[i])) { + if (!event.args[i].eq(BigNumber.from(expectedArgs[i]))) { + invalidParamsButExists = true; + break; + } + } else if (event.args[i].constructor == Array) { + let params = event.args[i]; + let expected = expectedArgs[i]; + for (let j = 0; j < params.length; j++) { + if (BigNumber.isBigNumber(params[j])) { + if (!params[j].eq(BigNumber.from(expected[j]))) { + invalidParamsButExists = true; + break; + } + } else if (params[j] != expected[j]) { + invalidParamsButExists = true; + break; + } + } + if (invalidParamsButExists) break; + } else if (event.args[i] != expectedArgs[i]) { + invalidParamsButExists = true; + break; + } + } + // Return if the for loop did not cause a break, so a match has been found, otherwise proceed with the event loop + if (!invalidParamsButExists) { + return; + } + } else { + return; + } + } + } + // Throw if the event args were not expected or the event was not found in the logs + if (invalidParamsButExists) { + logger.throwError(`Event "${name}" found in logs but with unexpected args`); + } else { + logger.throwError(`Event "${name}" not found in given transaction log`); + } + } else { + logger.throwError('No events were emitted'); + } +} + +export function computeContractAddress(deployerAddress: string, nonce: number): string { + const hexNonce = hexlify(nonce); + return '0x' + keccak256(RLP.encode([deployerAddress, hexNonce])).substr(26); +} + +export function getChainId(): number { + return hre.network.config.chainId || HARDHAT_CHAINID; +} + +export function getAbbreviation(handle: string) { + let slice = handle.substr(0, 4); + if (slice.charAt(3) == ' ') { + slice = slice.substr(0, 3); + } + return slice; +} + +export async function waitForTx( + tx: Promise | TransactionResponse, + skipCheck = false +): Promise { + if (!skipCheck) await expect(tx).to.not.be.reverted; + return await (await tx).wait(); +} + +// export async function getBlockNumber(): Promise { +// return (await helper.getBlockNumber()).toNumber(); +// } + +export async function resetFork(): Promise { + await hre.network.provider.request({ + method: 'hardhat_reset', + params: [ + { + forking: { + jsonRpcUrl: `https://eth-mainnet.alchemyapi.io/v2/${process.env.ALCHEMY_KEY}`, + blockNumber: 12012081, + }, + }, + ], + }); + console.log('\t> Fork reset'); + + await hre.network.provider.request({ + method: 'evm_setNextBlockTimestamp', + params: [1614290545], // Original block timestamp + 1 + }); + + console.log('\t> Timestamp reset to 1614290545'); +} + +export async function getTimestamp(): Promise { + const blockNumber = await hre.ethers.provider.send('eth_blockNumber', []); + const block = await hre.ethers.provider.send('eth_getBlockByNumber', [blockNumber, false]); + return block.timestamp; +} + +export async function setNextBlockTimestamp(timestamp: number): Promise { + await hre.ethers.provider.send('evm_setNextBlockTimestamp', [timestamp]); +} + +export async function mine(blocks: number): Promise { + for (let i = 0; i < blocks; i++) { + await hre.ethers.provider.send('evm_mine', []); + } +} + +let snapshotId: string = '0x1'; +export async function takeSnapshot() { + snapshotId = await hre.ethers.provider.send('evm_snapshot', []); +} + +export async function revertToSnapshot() { + await hre.ethers.provider.send('evm_revert', [snapshotId]); +} + +// export async function cancelWithPermitForAll(nft: string = lensHub.address) { +// const nftContract = LensHub__factory.connect(nft, testWallet); +// const name = await nftContract.name(); +// const nonce = (await nftContract.sigNonces(testWallet.address)).toNumber(); +// const { v, r, s } = await getPermitForAllParts( +// nft, +// name, +// testWallet.address, +// testWallet.address, +// false, +// nonce, +// MAX_UINT256 +// ); +// await nftContract.permitForAll(testWallet.address, testWallet.address, false, { +// v, +// r, +// s, +// deadline: MAX_UINT256, +// }); +// } + +// export async function getPermitParts( +// nft: string, +// name: string, +// spender: string, +// tokenId: BigNumberish, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildPermitParams(nft, name, spender, tokenId, nonce, deadline); +// return await getSig(msgParams); +// } + +// export async function getPermitForAllParts( +// nft: string, +// name: string, +// owner: string, +// operator: string, +// approved: boolean, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildPermitForAllParams(nft, name, owner, operator, approved, nonce, deadline); +// return await getSig(msgParams); +// } + +// export async function getBurnWithSigparts( +// nft: string, +// name: string, +// tokenId: BigNumberish, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildBurnWithSigParams(nft, name, tokenId, nonce, deadline); +// return await getSig(msgParams); +// } + +// export async function getDelegateBySigParts( +// nft: string, +// name: string, +// delegator: string, +// delegatee: string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildDelegateBySigParams(nft, name, delegator, delegatee, nonce, deadline); +// return await getSig(msgParams); +// } + +const buildDelegateBySigParams = ( + nft: string, + name: string, + delegator: string, + delegatee: string, + nonce: number, + deadline: string +) => ({ + types: { + DelegateBySig: [ + { name: 'delegator', type: 'address' }, + { name: 'delegatee', type: 'address' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: name, + version: '1', + chainId: getChainId(), + verifyingContract: nft, + }, + value: { + delegator: delegator, + delegatee: delegatee, + nonce: nonce, + deadline: deadline, + }, +}); + +// export async function getSetFollowModuleWithSigParts( +// profileId: BigNumberish, +// followModule: string, +// followModuleData: Bytes | string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildSetFollowModuleWithSigParams( +// profileId, +// followModule, +// followModuleData, +// nonce, +// deadline +// ); +// return await getSig(msgParams); +// } + +// export async function getSetDispatcherWithSigParts( +// profileId: BigNumberish, +// dispatcher: string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildSetDispatcherWithSigParams(profileId, dispatcher, nonce, deadline); +// return await getSig(msgParams); +// } + +// export async function getSetProfileImageURIWithSigParts( +// profileId: BigNumberish, +// imageURI: string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildSetProfileImageURIWithSigParams(profileId, imageURI, nonce, deadline); +// return await getSig(msgParams); +// } + +// export async function getSetDefaultProfileWithSigParts( +// profileId: BigNumberish, +// wallet: string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildSetDefaultProfileWithSigParams(profileId, wallet, nonce, deadline); +// return await getSig(msgParams); +// } + +// export async function getSetFollowNFTURIWithSigParts( +// profileId: BigNumberish, +// followNFTURI: string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildSetFollowNFTURIWithSigParams(profileId, followNFTURI, nonce, deadline); +// return await getSig(msgParams); +// } + +// export async function getPostWithSigParts( +// profileId: BigNumberish, +// contentURI: string, +// collectModule: string, +// collectModuleData: Bytes | string, +// referenceModule: string, +// referenceModuleData: Bytes | string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildPostWithSigParams( +// profileId, +// contentURI, +// collectModule, +// collectModuleData, +// referenceModule, +// referenceModuleData, +// nonce, +// deadline +// ); +// return await getSig(msgParams); +// } + +// export async function getCommentWithSigParts( +// profileId: BigNumberish, +// contentURI: string, +// profileIdPointed: BigNumberish, +// pubIdPointed: string, +// collectModule: string, +// collectModuleData: Bytes | string, +// referenceModule: string, +// referenceModuleData: Bytes | string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildCommentWithSigParams( +// profileId, +// contentURI, +// profileIdPointed, +// pubIdPointed, +// collectModule, +// collectModuleData, +// referenceModule, +// referenceModuleData, +// nonce, +// deadline +// ); +// return await getSig(msgParams); +// } + +// export async function getMirrorWithSigParts( +// profileId: BigNumberish, +// profileIdPointed: BigNumberish, +// pubIdPointed: string, +// referenceModule: string, +// referenceModuleData: Bytes | string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildMirrorWithSigParams( +// profileId, +// profileIdPointed, +// pubIdPointed, +// referenceModule, +// referenceModuleData, +// nonce, +// deadline +// ); +// return await getSig(msgParams); +// } + +// export async function getFollowWithSigParts( +// profileIds: string[] | number[], +// datas: Bytes[] | string[], +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildFollowWithSigParams(profileIds, datas, nonce, deadline); +// return await getSig(msgParams); +// } + +// export async function getCollectWithSigParts( +// profileId: BigNumberish, +// pubId: string, +// data: Bytes | string, +// nonce: number, +// deadline: string +// ): Promise<{ v: number; r: string; s: string }> { +// const msgParams = buildCollectWithSigParams(profileId, pubId, data, nonce, deadline); +// return await getSig(msgParams); +// } + +// Modified from AaveTokenV2 repo +const buildPermitParams = ( + nft: string, + name: string, + spender: string, + tokenId: BigNumberish, + nonce: number, + deadline: string +) => ({ + types: { + Permit: [ + { name: 'spender', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: name, + version: '1', + chainId: getChainId(), + verifyingContract: nft, + }, + value: { + spender: spender, + tokenId: tokenId, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildPermitForAllParams = ( + nft: string, + name: string, + owner: string, + operator: string, + approved: boolean, + nonce: number, + deadline: string +) => ({ + types: { + PermitForAll: [ + { name: 'owner', type: 'address' }, + { name: 'operator', type: 'address' }, + { name: 'approved', type: 'bool' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: name, + version: '1', + chainId: getChainId(), + verifyingContract: nft, + }, + value: { + owner: owner, + operator: operator, + approved: approved, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildBurnWithSigParams = ( + nft: string, + name: string, + tokenId: BigNumberish, + nonce: number, + deadline: string +) => ({ + types: { + BurnWithSig: [ + { name: 'tokenId', type: 'uint256' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: { + name: name, + version: '1', + chainId: getChainId(), + verifyingContract: nft, + }, + value: { + tokenId: tokenId, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetFollowModuleWithSigParams = ( + profileId: BigNumberish, + followModule: string, + followModuleData: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + SetFollowModuleWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'followModule', type: 'address' }, + { name: 'followModuleData', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + followModule: followModule, + followModuleData: followModuleData, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetDispatcherWithSigParams = ( + profileId: BigNumberish, + dispatcher: string, + nonce: number, + deadline: string +) => ({ + types: { + SetDispatcherWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'dispatcher', type: 'address' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + dispatcher: dispatcher, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetProfileImageURIWithSigParams = ( + profileId: BigNumberish, + imageURI: string, + nonce: number, + deadline: string +) => ({ + types: { + SetProfileImageURIWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'imageURI', type: 'string' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + imageURI: imageURI, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetDefaultProfileWithSigParams = ( + profileId: BigNumberish, + wallet: string, + nonce: number, + deadline: string +) => ({ + types: { + SetDefaultProfileWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'wallet', type: 'address' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + wallet: wallet, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildSetFollowNFTURIWithSigParams = ( + profileId: BigNumberish, + followNFTURI: string, + nonce: number, + deadline: string +) => ({ + types: { + SetFollowNFTURIWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'followNFTURI', type: 'string' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + followNFTURI: followNFTURI, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildPostWithSigParams = ( + profileId: BigNumberish, + contentURI: string, + collectModule: string, + collectModuleData: Bytes | string, + referenceModule: string, + referenceModuleData: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + PostWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'contentURI', type: 'string' }, + { name: 'collectModule', type: 'address' }, + { name: 'collectModuleData', type: 'bytes' }, + { name: 'referenceModule', type: 'address' }, + { name: 'referenceModuleData', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + contentURI: contentURI, + collectModule: collectModule, + collectModuleData: collectModuleData, + referenceModule: referenceModule, + referenceModuleData: referenceModuleData, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildCommentWithSigParams = ( + profileId: BigNumberish, + contentURI: string, + profileIdPointed: BigNumberish, + pubIdPointed: string, + collectModule: string, + collectModuleData: Bytes | string, + referenceModule: string, + referenceModuleData: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + CommentWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'contentURI', type: 'string' }, + { name: 'profileIdPointed', type: 'uint256' }, + { name: 'pubIdPointed', type: 'uint256' }, + { name: 'collectModule', type: 'address' }, + { name: 'collectModuleData', type: 'bytes' }, + { name: 'referenceModule', type: 'address' }, + { name: 'referenceModuleData', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + contentURI: contentURI, + profileIdPointed: profileIdPointed, + pubIdPointed: pubIdPointed, + collectModule: collectModule, + collectModuleData: collectModuleData, + referenceModule: referenceModule, + referenceModuleData: referenceModuleData, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildMirrorWithSigParams = ( + profileId: BigNumberish, + profileIdPointed: BigNumberish, + pubIdPointed: string, + referenceModule: string, + referenceModuleData: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + MirrorWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'profileIdPointed', type: 'uint256' }, + { name: 'pubIdPointed', type: 'uint256' }, + { name: 'referenceModule', type: 'address' }, + { name: 'referenceModuleData', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + profileIdPointed: profileIdPointed, + pubIdPointed: pubIdPointed, + referenceModule: referenceModule, + referenceModuleData: referenceModuleData, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildFollowWithSigParams = ( + profileIds: string[] | number[], + datas: Bytes[] | string[], + nonce: number, + deadline: string +) => ({ + types: { + FollowWithSig: [ + { name: 'profileIds', type: 'uint256[]' }, + { name: 'datas', type: 'bytes[]' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileIds: profileIds, + datas: datas, + nonce: nonce, + deadline: deadline, + }, +}); + +const buildCollectWithSigParams = ( + profileId: BigNumberish, + pubId: string, + data: Bytes | string, + nonce: number, + deadline: string +) => ({ + types: { + CollectWithSig: [ + { name: 'profileId', type: 'uint256' }, + { name: 'pubId', type: 'uint256' }, + { name: 'data', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + ], + }, + domain: domain(), + value: { + profileId: profileId, + pubId: pubId, + data: data, + nonce: nonce, + deadline: deadline, + }, +}); + +// async function getSig(msgParams: { +// domain: any; +// types: any; +// value: any; +// }): Promise<{ v: number; r: string; s: string }> { +// const sig = await testWallet._signTypedData(msgParams.domain, msgParams.types, msgParams.value); +// return utils.splitSignature(sig); +// } + +function domain(): { name: string; version: string; chainId: number; verifyingContract: string } { + return { + name: LENS_HUB_NFT_NAME, + version: '1', + chainId: getChainId(), + verifyingContract: lensHub.address, + }; +} diff --git a/lens-protocol/modules/test/modules/collect/ERC4626-collect-module.spec.ts b/lens-protocol/modules/test/modules/collect/ERC4626-collect-module.spec.ts new file mode 100644 index 0000000..90488df --- /dev/null +++ b/lens-protocol/modules/test/modules/collect/ERC4626-collect-module.spec.ts @@ -0,0 +1,908 @@ +import { BigNumber } from '@ethersproject/bignumber'; +import { parseEther } from '@ethersproject/units'; +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { MAX_UINT256, ONE_DAY, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { getTimestamp, matchEvent, setNextBlockTimestamp, waitForTx } from '../../helpers/utils'; +import { + abiCoder, + BPS_MAX, + currency, + currencyTwo, + FIRST_PROFILE_ID, + governance, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + moduleGlobals, + REFERRAL_FEE_BPS, + TREASURY_FEE_BPS, + user, + anotherUser, + treasury, + mockVault, + mockVaultTwo, + erc4626FeeCollectModule, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('ERC4626 Collect Module', function () { + const DEFAULT_COLLECT_PRICE = parseEther('10'); + const DEFAULT_COLLECT_LIMIT = 3; + const DEFAULT_FOLLOWER_ONLY = true; + const DEFAULT_END_TIMESTAMP = 0; // no endtime + + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: user.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(erc4626FeeCollectModule.address, true) + ).to.not.be.reverted; + await expect( + moduleGlobals.connect(governance).whitelistCurrency(currency.address, true) + ).to.not.be.reverted; + // currencyTwo must NOT be on the whitelist + await expect( + moduleGlobals.connect(governance).whitelistCurrency(currencyTwo.address, false) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + context('Publication Creation', function () { + it('user should fail to post with ERC4626 fee collect module using a vault with an unwhitelisted currency', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVaultTwo.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('user should fail to post with ERC4626 fee collect module if not called via the Hub', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVaultTwo.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + erc4626FeeCollectModule + .connect(user) + .initializePublicationCollectModule(FIRST_PROFILE_ID, 1, collectModuleInitData) + ).to.be.revertedWith(ERRORS.NOT_HUB); + }); + + it('user should fail to post with ERC4626 fee collect module using zero recipient', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + ZERO_ADDRESS, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('user should fail to post with ERC4626 fee collect module using referral fee greater than max BPS', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + 10001, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('user should fail to post with ERC4626 fee collect module using end timestamp in the past', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + 9999, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + 1, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + }); + + context('Collecting', function () { + beforeEach(async function () { + const currentTimePlus1Day = BigNumber.from(await getTimestamp()).add(ONE_DAY); + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + currentTimePlus1Day, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('Second User should fail to collect without following if followerOnly is true', async function () { + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('Second User should be able to collect without following if followerOnly is false', async function () { + // Post new publication with followerOnly == false + const currentTimePlus1Day = BigNumber.from(await getTimestamp()).add(ONE_DAY); + const collectModuleInitDataTwo = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + false, // followerOnly = false + currentTimePlus1Day, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitDataTwo, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const dataTwo = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(erc4626FeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + // PubID = 2 here to test the followerOnly = false pub + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 2, dataTwo) + ).to.not.be.reverted; + }); + + it('Second User should fail to collect passing a different expected price in data', async function () { + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE.div(2)] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('Second User should fail to collect passing a different expected currency in data', async function () { + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const data = abiCoder.encode(['address', 'uint256'], [user.address, DEFAULT_COLLECT_PRICE]); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('Second User should fail to collect without first approving module with currency', async function () { + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.ERC20_INSUFFICIENT_ALLOWANCE); + }); + + it('Second User should fail to collect after publication has expired', async function () { + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + + // Fast forward 2 days, publication expired after 1 day + await setNextBlockTimestamp( + parseInt(BigNumber.from(await getTimestamp()).toString()) + ONE_DAY + ); + + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.COLLECT_EXPIRED); + }); + + it('Second User should mirror the original post, fail to collect from their mirror without following the original profile', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('Second User should mirror the original post, fail to collect from their mirror passing a different expected price in data', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE.div(2)] + ); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('Second User should mirror the original post, fail to collect from their mirror passing a different expected currency in data', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode(['address', 'uint256'], [user.address, DEFAULT_COLLECT_PRICE]); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + }); + }); + + context('Scenarios', function () { + it('User should post with ERC4626 fee collect module as the collect module and data, correct events should be emitted', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + const tx = lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }); + + const receipt = await waitForTx(tx); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'PostCreated', [ + FIRST_PROFILE_ID, + 1, + MOCK_URI, + erc4626FeeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + [], + await getTimestamp(), + ]); + }); + + it('User should post with ERC4626 fee collect module as the collect module and data, fetched publication data should be accurate', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const fetchedData = await erc4626FeeCollectModule.getPublicationData(FIRST_PROFILE_ID, 1); + expect(fetchedData.collectLimit).to.eq(DEFAULT_COLLECT_LIMIT); + expect(fetchedData.amount).to.eq(DEFAULT_COLLECT_PRICE); + expect(fetchedData.recipient).to.eq(user.address); + expect(fetchedData.currency).to.eq(currency.address); + expect(fetchedData.referralFee).to.eq(REFERRAL_FEE_BPS); + expect(fetchedData.vault).to.eq(mockVault.address); + expect(fetchedData.followerOnly).to.eq(DEFAULT_FOLLOWER_ONLY); + }); + + it('User should post with ERC4626 fee collect module as the collect module and data, user two follows, then collects and pays fee, fee distribution is valid', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(erc4626FeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedRecipientAmount = + BigNumber.from(DEFAULT_COLLECT_PRICE).sub(expectedTreasuryAmount); + + expect(await currency.balanceOf(anotherUser.address)).to.eq( + BigNumber.from(MAX_UINT256).sub(DEFAULT_COLLECT_PRICE) + ); + // Exchange rate is 1:1 assets:shares so same amount used + expect(await mockVault.balanceOf(user.address)).to.eq(expectedRecipientAmount); + expect(await currency.balanceOf(user.address)).to.eq(0); // no currency amount received + expect(await currency.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount); + }); + + it('User should post with ERC4626 fee collect module as the collect module and data, user two follows, then collects and pays fee, treasury fee is 0%', async function () { + // Set treasury fee to 0% (0 bps) + const NEW_TREASURY_FEE_BPS = 0; + await moduleGlobals.connect(governance).setTreasuryFee(NEW_TREASURY_FEE_BPS); + + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(erc4626FeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(NEW_TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedRecipientAmount = + BigNumber.from(DEFAULT_COLLECT_PRICE).sub(expectedTreasuryAmount); + + expect(await currency.balanceOf(anotherUser.address)).to.eq( + BigNumber.from(MAX_UINT256).sub(DEFAULT_COLLECT_PRICE) + ); + // Exchange rate is 1:1 assets:shares so same amount used + expect(await mockVault.balanceOf(user.address)).to.eq(expectedRecipientAmount); + expect(await currency.balanceOf(user.address)).to.eq(0); // no currency amount received + expect(await currency.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount); + }); + + it('User should post with ERC4626 fee collect module as the collect module and data, user two follows, then collects twice, fee distribution is valid', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(erc4626FeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedRecipientAmount = + BigNumber.from(DEFAULT_COLLECT_PRICE).sub(expectedTreasuryAmount); + + expect(await currency.balanceOf(anotherUser.address)).to.eq( + BigNumber.from(MAX_UINT256).sub(BigNumber.from(DEFAULT_COLLECT_PRICE).mul(2)) + ); + // Exchange rate is 1:1 assets:shares so same amount used + expect(await mockVault.balanceOf(user.address)).to.eq(expectedRecipientAmount.mul(2)); + expect(await currency.balanceOf(user.address)).to.eq(0); // no currency amount received + expect(await currency.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount.mul(2)); + }); + + it('User should post with ERC4626 fee collect module as the collect module and data, user two mirrors, follows, then collects from their mirror and pays fee, fee distribution is valid', async function () { + // Set treasury fee to 0% (0 bps) + const NEW_TREASURY_FEE_BPS = 0; + await moduleGlobals.connect(governance).setTreasuryFee(NEW_TREASURY_FEE_BPS); + + const secondProfileId = FIRST_PROFILE_ID + 1; + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(erc4626FeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(NEW_TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedReferralAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .sub(expectedTreasuryAmount) + .mul(REFERRAL_FEE_BPS) + .div(BPS_MAX); + const expectedReferrerAmount = BigNumber.from(MAX_UINT256) + .sub(DEFAULT_COLLECT_PRICE) + .add(expectedReferralAmount); + const expectedRecipientAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .sub(expectedTreasuryAmount) + .sub(expectedReferralAmount); + + expect(await currency.balanceOf(anotherUser.address)).to.eq(expectedReferrerAmount); + expect(await mockVault.balanceOf(anotherUser.address)).to.eq(0); // referrer receives currency not shares + // Exchange rate is 1:1 assets:shares so same amount used + expect(await mockVault.balanceOf(user.address)).to.eq(expectedRecipientAmount); + expect(await currency.balanceOf(user.address)).to.eq(0); // no currency amount received by recipient + expect(await currency.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount); + }); + + it('User should post with ERC4626 fee collect module as the collect module and data, with no referral fee, user two mirrors, follows, then collects from their mirror and pays fee, fee distribution is valid', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + 0, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(erc4626FeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedRecipientAmount = + BigNumber.from(DEFAULT_COLLECT_PRICE).sub(expectedTreasuryAmount); + + expect(await currency.balanceOf(anotherUser.address)).to.eq( + BigNumber.from(MAX_UINT256).sub(DEFAULT_COLLECT_PRICE) + ); + // Exchange rate is 1:1 assets:shares so same amount used + expect(await mockVault.balanceOf(user.address)).to.eq(expectedRecipientAmount); + expect(await currency.balanceOf(user.address)).to.eq(0); // no currency amount received by recipient + expect(await currency.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount); + }); + + it('User should post with ERC4626 fee collect module as the collect module and data, user two mirrors, follows, then collects once from the original, twice from the mirror, and fails to collect a third time from either the mirror or the original', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + const collectModuleInitData = abiCoder.encode( + ['uint96', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint72'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + mockVault.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: erc4626FeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(erc4626FeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.MINT_LIMIT_EXCEEDED); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.be.revertedWith(ERRORS.MINT_LIMIT_EXCEEDED); + }); + }); +}); diff --git a/lens-protocol/modules/test/modules/collect/aave-fee-collect-module.spec.ts b/lens-protocol/modules/test/modules/collect/aave-fee-collect-module.spec.ts new file mode 100644 index 0000000..074296a --- /dev/null +++ b/lens-protocol/modules/test/modules/collect/aave-fee-collect-module.spec.ts @@ -0,0 +1,927 @@ +import { BigNumber } from '@ethersproject/bignumber'; +import { parseEther } from '@ethersproject/units'; +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { MAX_UINT256, ONE_DAY, ZERO_ADDRESS } from '../../helpers/constants'; +import { ERRORS } from '../../helpers/errors'; +import { getTimestamp, matchEvent, setNextBlockTimestamp, waitForTx } from '../../helpers/utils'; +import { + abiCoder, + BPS_MAX, + currency, + currencyTwo, + aCurrency, + FIRST_PROFILE_ID, + governance, + lensHub, + aaveFeeCollectModule, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_PROFILE_URI, + MOCK_URI, + moduleGlobals, + REFERRAL_FEE_BPS, + TREASURY_FEE_BPS, + user, + anotherUser, + treasury, +} from '../../__setup.spec'; + +makeSuiteCleanRoom('Aave Fee Collect Module', function () { + const DEFAULT_COLLECT_PRICE = parseEther('10'); + const DEFAULT_COLLECT_LIMIT = 3; + const DEFAULT_FOLLOWER_ONLY = true; + const DEFAULT_END_TIMESTAMP = 0; // no endtime + + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: user.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(governance).whitelistCollectModule(aaveFeeCollectModule.address, true) + ).to.not.be.reverted; + await expect( + moduleGlobals.connect(governance).whitelistCurrency(currency.address, true) + ).to.not.be.reverted; + await expect( + moduleGlobals.connect(governance).whitelistCurrency(currencyTwo.address, true) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + context('Publication Creation', function () { + it('user should fail to post with aave fee collect module using unwhitelisted currency', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + anotherUser.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('user should fail to post with aave fee collect module using zero recipient', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + ZERO_ADDRESS, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('user should fail to post with aave fee collect module using referral fee greater than max BPS', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + 10001, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('user should fail to post with aave fee collect module using end timestamp in the past', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + 9999, + currency.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + 1, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + }); + + context('Collecting', function () { + beforeEach(async function () { + const currentTimePlus1Day = BigNumber.from(await getTimestamp()).add(ONE_DAY); + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + currentTimePlus1Day, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('Second User should fail to collect without following if followerOnly is true', async function () { + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('Second User should be able to collect without following if followerOnly is false', async function () { + // Post new publication with followerOnly == false + const currentTimePlus1Day = BigNumber.from(await getTimestamp()).add(ONE_DAY); + const collectModuleInitDataTwo = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + REFERRAL_FEE_BPS, + false, // followerOnly = false + currentTimePlus1Day, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitDataTwo, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const dataTwo = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(aaveFeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + // PubID = 2 here to test the followerOnly = false pub + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 2, dataTwo) + ).to.not.be.reverted; + }); + + it('Second User should fail to collect passing a different expected price in data', async function () { + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE.div(2)] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('Second User should fail to collect passing a different expected currency in data', async function () { + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const data = abiCoder.encode(['address', 'uint256'], [user.address, DEFAULT_COLLECT_PRICE]); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('Second User should fail to collect without first approving module with currency', async function () { + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.ERC20_INSUFFICIENT_ALLOWANCE); + }); + + it('Second User should fail to collect after publication has expired', async function () { + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + + // Fast forward 2 days, publication expired after 1 day + await setNextBlockTimestamp( + parseInt(BigNumber.from(await getTimestamp()).toString()) + ONE_DAY + ); + + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.COLLECT_EXPIRED); + }); + + it('Second User should mirror the original post, fail to collect from their mirror without following the original profile', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('Second User should mirror the original post, fail to collect from their mirror passing a different expected price in data', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE.div(2)] + ); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('Second User should mirror the original post, fail to collect from their mirror passing a different expected currency in data', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode(['address', 'uint256'], [user.address, DEFAULT_COLLECT_PRICE]); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + }); + }); + + context('Scenarios', function () { + it('User should post with aave fee collect module as the collect module and data, correct events should be emitted', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + const tx = lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }); + + const receipt = await waitForTx(tx); + + expect(receipt.logs.length).to.eq(1); + matchEvent(receipt, 'PostCreated', [ + FIRST_PROFILE_ID, + 1, + MOCK_URI, + aaveFeeCollectModule.address, + collectModuleInitData, + ZERO_ADDRESS, + [], + await getTimestamp(), + ]); + }); + + it('User should post with aave fee collect module as the collect module and data, fetched publication data should be accurate', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + const fetchedData = await aaveFeeCollectModule.getPublicationData(FIRST_PROFILE_ID, 1); + expect(fetchedData.collectLimit).to.eq(DEFAULT_COLLECT_LIMIT); + expect(fetchedData.amount).to.eq(DEFAULT_COLLECT_PRICE); + expect(fetchedData.recipient).to.eq(user.address); + expect(fetchedData.currency).to.eq(currency.address); + expect(fetchedData.referralFee).to.eq(REFERRAL_FEE_BPS); + }); + + it('User should post with aave fee collect module as the collect module and data, user two follows, then collects and pays fee with currencyTwo, fee distribution is by currencyTwo', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currencyTwo.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currencyTwo.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currencyTwo.connect(anotherUser).approve(aaveFeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currencyTwo.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedRecipientAmount = + BigNumber.from(DEFAULT_COLLECT_PRICE).sub(expectedTreasuryAmount); + + expect(await currencyTwo.balanceOf(anotherUser.address)).to.eq( + BigNumber.from(MAX_UINT256).sub(DEFAULT_COLLECT_PRICE) + ); + expect(await currencyTwo.balanceOf(user.address)).to.eq(expectedRecipientAmount); + expect(await currencyTwo.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount); + }); + + it('User should post with aave fee collect module as the collect module and data, user two follows, then collects and pays fee, fee distribution is valid', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(aaveFeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedRecipientAmount = + BigNumber.from(DEFAULT_COLLECT_PRICE).sub(expectedTreasuryAmount); + + expect(await currency.balanceOf(anotherUser.address)).to.eq( + BigNumber.from(MAX_UINT256).sub(DEFAULT_COLLECT_PRICE) + ); + expect(await aCurrency.balanceOf(user.address)).to.eq(expectedRecipientAmount); + expect(await currency.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount); + }); + + it('User should post with aave fee collect module as the collect module and data, user two follows, then collects twice, fee distribution is valid', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(aaveFeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedRecipientAmount = + BigNumber.from(DEFAULT_COLLECT_PRICE).sub(expectedTreasuryAmount); + + expect(await currency.balanceOf(anotherUser.address)).to.eq( + BigNumber.from(MAX_UINT256).sub(BigNumber.from(DEFAULT_COLLECT_PRICE).mul(2)) + ); + expect(await aCurrency.balanceOf(user.address)).to.eq(expectedRecipientAmount.mul(2)); + expect(await currency.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount.mul(2)); + }); + + it('User should post with aave fee collect module as the collect module and data, user two mirrors, follows, then collects from their mirror and pays fee, fee distribution is valid', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(aaveFeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedReferralAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .sub(expectedTreasuryAmount) + .mul(REFERRAL_FEE_BPS) + .div(BPS_MAX); + const expectedReferrerAmount = BigNumber.from(MAX_UINT256) + .sub(DEFAULT_COLLECT_PRICE) + .add(expectedReferralAmount); + const expectedRecipientAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .sub(expectedTreasuryAmount) + .sub(expectedReferralAmount); + + expect(await currency.balanceOf(anotherUser.address)).to.eq(expectedReferrerAmount); + expect(await aCurrency.balanceOf(anotherUser.address)).to.eq(0); + expect(await aCurrency.balanceOf(user.address)).to.eq(expectedRecipientAmount); + expect(await currency.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount); + }); + + it('User should post with aave fee collect module as the collect module and data, with no referral fee, user two mirrors, follows, then collects from their mirror and pays fee, fee distribution is valid', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + 0, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(aaveFeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedRecipientAmount = + BigNumber.from(DEFAULT_COLLECT_PRICE).sub(expectedTreasuryAmount); + + expect(await currency.balanceOf(anotherUser.address)).to.eq( + BigNumber.from(MAX_UINT256).sub(DEFAULT_COLLECT_PRICE) + ); + expect(await aCurrency.balanceOf(user.address)).to.eq(expectedRecipientAmount); + expect(await currency.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount); + }); + + it('User should post with aave fee collect module as the collect module and data, user two mirrors, follows, then collects once from the original, twice from the mirror, and fails to collect a third time from either the mirror or the original', async function () { + const secondProfileId = FIRST_PROFILE_ID + 1; + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currency.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: secondProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: 1, + referenceModule: ZERO_ADDRESS, + referenceModuleData: [], + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect(currency.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currency.connect(anotherUser).approve(aaveFeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.not.be.reverted; + + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.be.revertedWith(ERRORS.MINT_LIMIT_EXCEEDED); + await expect( + lensHub.connect(anotherUser).collect(secondProfileId, 1, data) + ).to.be.revertedWith(ERRORS.MINT_LIMIT_EXCEEDED); + }); + + it('User should post with aave fee collect module as the collect module but asset not supported by Aave, user two collects, user gets paid in base currency and not aTokens', async function () { + const collectModuleInitData = abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'uint16', 'bool', 'uint40'], + [ + DEFAULT_COLLECT_LIMIT, + DEFAULT_COLLECT_PRICE, + currencyTwo.address, + user.address, + REFERRAL_FEE_BPS, + DEFAULT_FOLLOWER_ONLY, + DEFAULT_END_TIMESTAMP, + ] + ); + await expect( + lensHub.connect(user).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: aaveFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ZERO_ADDRESS, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'usertwo', + imageURI: MOCK_PROFILE_URI, + followModule: ZERO_ADDRESS, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + + await expect(currencyTwo.mint(anotherUser.address, MAX_UINT256)).to.not.be.reverted; + await expect( + currencyTwo.connect(anotherUser).approve(aaveFeeCollectModule.address, MAX_UINT256) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const data = abiCoder.encode( + ['address', 'uint256'], + [currencyTwo.address, DEFAULT_COLLECT_PRICE] + ); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, 1, data) + ).to.not.be.reverted; + + const expectedTreasuryAmount = BigNumber.from(DEFAULT_COLLECT_PRICE) + .mul(TREASURY_FEE_BPS) + .div(BPS_MAX); + const expectedRecipientAmount = + BigNumber.from(DEFAULT_COLLECT_PRICE).sub(expectedTreasuryAmount); + + expect(await currencyTwo.balanceOf(user.address)).to.eq(expectedRecipientAmount); + expect(await aCurrency.balanceOf(user.address)).to.eq(0); + expect(await currencyTwo.balanceOf(treasury.address)).to.eq(expectedTreasuryAmount); + }); + }); +}); diff --git a/lens-protocol/modules/test/modules/collect/auction-collect-module.spec.ts b/lens-protocol/modules/test/modules/collect/auction-collect-module.spec.ts new file mode 100644 index 0000000..b950515 --- /dev/null +++ b/lens-protocol/modules/test/modules/collect/auction-collect-module.spec.ts @@ -0,0 +1,1737 @@ +import { BigNumber, BigNumberish } from '@ethersproject/bignumber'; +import { parseEther } from '@ethersproject/units'; +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { AuctionCollectModule__factory, FollowNFT__factory } from '../../../typechain'; +import { ERRORS } from '../../helpers/errors'; +import { + abiCoder, + auctionCollectModule, + BPS_MAX, + chainId, + currency, + feeRecipient, + FIRST_PROFILE_ID, + FIRST_PUB_ID, + freeCollectModule, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_URI, + moduleGlobals, + anotherUser, + REFERRAL_FEE_BPS, + user, + FIRST_FOLLOW_NFT_ID, + deployer, + thirdUser, + treasury, + TREASURY_FEE_BPS, + governance, + DEFAULT_AMOUNT, +} from './../../__setup.spec'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { publisher } from '../../__setup.spec'; +import { getTimestamp, matchEvent, setNextBlockTimestamp, waitForTx } from '../../helpers/utils'; +import { signBidWithSigMessage } from '../../helpers/signatures/modules/collect/auction-collect-module'; +import { Domain } from '../../helpers/signatures/utils'; + +export let BID_WITH_SIG_DOMAIN: Domain; + +makeSuiteCleanRoom('AuctionCollectModule', function () { + const ONE_DAY_IN_SECONDS = BigNumber.from(24 * 3600); + const TEN_MINUTES_IN_SECONDS = BigNumber.from(10 * 60); + const DEFAULT_RESERVE_PRICE = parseEther('1'); + const DEFAULT_MIN_TIME_AFTER_BID = TEN_MINUTES_IN_SECONDS; + const DEFAULT_MIN_BID_INCREMENT = parseEther('0.1'); + const DEFAULT_DURATION = ONE_DAY_IN_SECONDS; + let bidder: SignerWithAddress; + let anotherBidder: SignerWithAddress; + + interface AuctionCollectModuleInitData { + availableSinceTimestamp?: BigNumber; + duration?: BigNumber; + minTimeAfterBid?: BigNumber; + reservePrice?: BigNumber; + minBidIncrement?: BigNumber; + referralFee?: number; + feeCurrency?: string; + recipient?: string; + onlyFollowers?: boolean; + } + + async function getAuctionCollectModuleInitData({ + availableSinceTimestamp = ethers.constants.Zero, + duration = DEFAULT_DURATION, + minTimeAfterBid = DEFAULT_MIN_TIME_AFTER_BID, + reservePrice = DEFAULT_RESERVE_PRICE, + minBidIncrement = DEFAULT_MIN_BID_INCREMENT, + referralFee = REFERRAL_FEE_BPS, + feeCurrency = currency.address, + recipient = feeRecipient.address, + onlyFollowers = false, + }: AuctionCollectModuleInitData): Promise { + return abiCoder.encode( + ['uint64', 'uint32', 'uint32', 'uint256', 'uint256', 'uint16', 'address', 'address', 'bool'], + [ + availableSinceTimestamp, + duration, + minTimeAfterBid, + reservePrice, + minBidIncrement, + referralFee, + feeCurrency, + recipient, + onlyFollowers, + ] + ); + } + + interface AuctionEndSimulationData { + profileId?: BigNumberish; + pubId?: BigNumberish; + secondsToBeElapsedAfterEnd?: BigNumberish; + } + + async function simulateAuctionEnd({ + profileId = FIRST_PROFILE_ID, + pubId = FIRST_PUB_ID, + secondsToBeElapsedAfterEnd = 1, + }: AuctionEndSimulationData) { + const endTimestamp = (await auctionCollectModule.getAuctionData(profileId, pubId)).endTimestamp; + setNextBlockTimestamp(endTimestamp.add(secondsToBeElapsedAfterEnd).toNumber()); + } + + interface MintAndApproveCurrency { + owner?: SignerWithAddress; + spender?: string; + amountToMint?: BigNumberish; + amountToApprove?: BigNumberish; + } + + async function mintAndApproveCurrency({ + owner = bidder, + spender = auctionCollectModule.address, + amountToMint = parseEther('100000'), + amountToApprove = ethers.constants.MaxUint256, + }: MintAndApproveCurrency) { + await currency.connect(owner).mint(owner.address, amountToMint); + await currency.connect(owner).approve(spender, amountToApprove); + } + + beforeEach(async function () { + BID_WITH_SIG_DOMAIN = { + name: 'AuctionCollectModule', + version: '1', + chainId: chainId, + verifyingContract: auctionCollectModule.address, + }; + bidder = user; + anotherBidder = anotherUser; + await expect( + lensHub.createProfile({ + to: publisher.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Publication creation', function () { + context('Negatives', function () { + it('User should fail to post setting zero duration', async function () { + const collectModuleInitData = await getAuctionCollectModuleInitData({ + duration: ethers.constants.Zero, + minTimeAfterBid: ethers.constants.Zero, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('User should fail to post setting a duration less than min time after bid', async function () { + const duration = ethers.constants.One; + expect(duration.lt(DEFAULT_MIN_TIME_AFTER_BID)).to.be.true; + const collectModuleInitData = await getAuctionCollectModuleInitData({ + duration: duration, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('User should fail to post using unwhitelisted currency', async function () { + const unwhitelistedCurrency = ethers.constants.AddressZero; + expect(await moduleGlobals.isCurrencyWhitelisted(unwhitelistedCurrency)).to.be.false; + const collectModuleInitData = await getAuctionCollectModuleInitData({ + feeCurrency: unwhitelistedCurrency, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('User should fail to post using referral fee greater than max BPS', async function () { + const referralFee = BPS_MAX + 1; + expect(referralFee).to.be.greaterThan(BPS_MAX); + const collectModuleInitData = await getAuctionCollectModuleInitData({ + referralFee: referralFee, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + }); + + context('Scenarios', function () { + it('User should succeed to create a publication when all parameters are valid and tx should emit expected event', async function () { + const collectModuleInitData = await getAuctionCollectModuleInitData({}); + const tx = lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }); + const txReceipt = await waitForTx(tx); + matchEvent( + txReceipt, + 'AuctionCreated', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + ethers.constants.Zero, + DEFAULT_DURATION, + DEFAULT_MIN_TIME_AFTER_BID, + DEFAULT_RESERVE_PRICE, + DEFAULT_MIN_BID_INCREMENT, + REFERRAL_FEE_BPS, + currency.address, + feeRecipient.address, + false, + ], + auctionCollectModule + ); + }); + + it('User should succeed to create a publication that burns the fees', async function () { + const collectModuleInitData = await getAuctionCollectModuleInitData({ + recipient: ethers.constants.AddressZero, + }); + const tx = lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }); + const txReceipt = await waitForTx(tx); + matchEvent( + txReceipt, + 'AuctionCreated', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + ethers.constants.Zero, + DEFAULT_DURATION, + DEFAULT_MIN_TIME_AFTER_BID, + DEFAULT_RESERVE_PRICE, + DEFAULT_MIN_BID_INCREMENT, + REFERRAL_FEE_BPS, + currency.address, + ethers.constants.AddressZero, + false, + ], + auctionCollectModule + ); + }); + }); + }); + + context('Bid', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('User should fail to bid for an unexistent publication', async function () { + const unexistentPubId = 69; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, unexistentPubId, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.PUBLICATION_DOES_NOT_EXIST); + }); + + it('User should fail to bid if the publication uses another collect module', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to bid if auction is not available yet', async function () { + const currentTimestamp = BigNumber.from(await getTimestamp()); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ + availableSinceTimestamp: currentTimestamp.add(ONE_DAY_IN_SECONDS), + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + const availableSinceTimestamp = ( + await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId) + ).availableSinceTimestamp; + expect(availableSinceTimestamp.gt(currentTimestamp)).to.be.true; + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to bid if auction has already ended', async function () { + let auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + let currentTimestamp = BigNumber.from(await getTimestamp()); + expect(currentTimestamp.gt(auction.availableSinceTimestamp)).to.be.true; + await mintAndApproveCurrency({}); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + expect(auction.startTimestamp.gte(currentTimestamp)).to.be.true; + await simulateAuctionEnd({}); + + // The tx below is just a dummy tx that does not affect the context of the test and, as a tx is needed to + // update the block timestamp, being able to verify the precondition of block.timestamp > auction.endTimestamp + // before doing the bid call. + lensHub.connect(publisher).setDefaultProfile(FIRST_PROFILE_ID); + + auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + currentTimestamp = BigNumber.from(await getTimestamp()); + expect(currentTimestamp.gt(auction.endTimestamp)).to.be.true; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT), 0) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to bid if does not have enough balance', async function () { + await mintAndApproveCurrency({ amountToMint: 0 }); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.ERC20_TRANSFER_EXCEEDS_BALANCE); + }); + + it('User should fail to bid if does not have enough allowance', async function () { + await mintAndApproveCurrency({ amountToApprove: 0 }); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.ERC20_INSUFFICIENT_ALLOWANCE); + }); + + it('User should fail to bid if placing the bid that starts the auction but it is below reserve price', async function () { + const reservePrice = ( + await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).reservePrice; + const bidAmountBelowReservePrice = parseEther('0.01'); + expect(reservePrice.gt(bidAmountBelowReservePrice)).to.be.true; + await mintAndApproveCurrency({}); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, bidAmountBelowReservePrice, 0) + ).to.be.revertedWith(ERRORS.INSUFFICIENT_BID_AMOUNT); + }); + + it('User should fail to bid if auction already started but bid does not comply min increment requirement', async function () { + await mintAndApproveCurrency({}); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.be.not.be.reverted; + const auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + const bidAmountWithoutEnoughIncrement = DEFAULT_AMOUNT.add(1); + expect(bidAmountWithoutEnoughIncrement.gt(DEFAULT_AMOUNT)).to.be.true; + expect( + bidAmountWithoutEnoughIncrement.sub(DEFAULT_AMOUNT).lt(auction.minBidIncrement) + ).to.be.true; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, bidAmountWithoutEnoughIncrement, 0) + ).to.be.revertedWith(ERRORS.INSUFFICIENT_BID_AMOUNT); + }); + + it('User should fail to bid if auction is only for followers and he is not following the publication owner', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + expect( + (await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId)).onlyFollowers + ).to.be.true; + await mintAndApproveCurrency({}); + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to bid if auction is only for followers and he followed publication owner after auction started', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + expect( + (await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId)).onlyFollowers + ).to.be.true; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + await expect( + lensHub.connect(anotherBidder).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + await expect( + auctionCollectModule + .connect(anotherBidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await expect(lensHub.connect(bidder).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const followNftAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const bidderFollowNftBalance = await FollowNFT__factory.connect( + followNftAddress, + bidder + ).balanceOf(bidder.address); + expect(bidderFollowNftBalance.gt(ethers.constants.Zero)).to.be.true; + await expect( + auctionCollectModule + .connect(bidder) + .bid( + FIRST_PROFILE_ID, + pubId, + DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT), + FIRST_FOLLOW_NFT_ID + 1 + ) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + }); + + context('Scenarios', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + }); + + it('Funds should be deposited into the contract when a bid is placed', async function () { + const bidderBalanceBeforeBid = await currency.balanceOf(bidder.address); + const moduleBalanceBeforeBid = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceBeforeBid.isZero()).to.be.true; + const tx = auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0); + const txReceipt = await waitForTx(tx); + const txTimestamp = await getTimestamp(); + const endTimestamp = DEFAULT_DURATION.add(txTimestamp); + matchEvent( + txReceipt, + 'BidPlaced', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + 0, + DEFAULT_AMOUNT, + 0, + bidder.address, + endTimestamp, + txTimestamp, + ], + auctionCollectModule + ); + const bidderBalanceAfterBid = await currency.balanceOf(bidder.address); + const moduleBalanceAfterBid = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceAfterBid.eq(DEFAULT_AMOUNT)).to.be.true; + expect(bidderBalanceAfterBid.eq(bidderBalanceBeforeBid.sub(DEFAULT_AMOUNT))).to.be.true; + }); + + it('Funds should be returned to previous winner when a better bid is placed by another bidder', async function () { + const bidderBalanceBeforeBids = await currency.balanceOf(bidder.address); + const anotherBidderBalanceBeforeBids = await currency.balanceOf(anotherBidder.address); + const moduleBalanceBeforeBids = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceBeforeBids.isZero()).to.be.true; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + const bidderBalanceAfter1stBid = await currency.balanceOf(bidder.address); + const anotherBidderAfter1stBid = await currency.balanceOf(anotherBidder.address); + const moduleBalanceAfter1stBid = await currency.balanceOf(auctionCollectModule.address); + expect(anotherBidderBalanceBeforeBids.eq(anotherBidderAfter1stBid)).to.be.true; + expect(moduleBalanceAfter1stBid.eq(DEFAULT_AMOUNT)).to.be.true; + expect(bidderBalanceAfter1stBid.eq(bidderBalanceBeforeBids.sub(DEFAULT_AMOUNT))).to.be.true; + const secondBidAmount = DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT); + await expect( + auctionCollectModule + .connect(anotherBidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, secondBidAmount, 0) + ).to.not.be.reverted; + const bidderBalanceAfterBids = await currency.balanceOf(bidder.address); + const anotherBidderBalanceAfterBids = await currency.balanceOf(anotherBidder.address); + const moduleBalanceAfterBids = await currency.balanceOf(auctionCollectModule.address); + expect(bidderBalanceAfterBids.eq(bidderBalanceAfterBids)).to.be.true; + expect(moduleBalanceAfterBids.eq(secondBidAmount)).to.be.true; + expect( + anotherBidderBalanceAfterBids.eq(anotherBidderBalanceBeforeBids.sub(secondBidAmount)) + ).to.be.true; + }); + + it('Auction should be extended by time set up by publisher in case of a bid placed when less than that time is left', async function () { + const oneMinuteInSeconds = BigNumber.from(60); + const fiveMinutes = oneMinuteInSeconds.mul(5); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ + minTimeAfterBid: fiveMinutes, + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + let auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId); + expect(auction.endTimestamp.eq(auction.startTimestamp.add(auction.duration))); + const endTimestampAfterFirstBid = auction.endTimestamp; + const secondBidTimestamp = endTimestampAfterFirstBid.sub(oneMinuteInSeconds).toNumber(); + await setNextBlockTimestamp(secondBidTimestamp); + await expect( + auctionCollectModule + .connect(anotherBidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT), 0) + ).to.not.be.reverted; + auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId); + expect(auction.endTimestamp.eq(auction.minTimeAfterBid + secondBidTimestamp)).to.be.true; + }); + + it('Referrer profile ID should be set properly and only at first bid of each one', async function () { + let bidAmount = DEFAULT_AMOUNT; + await lensHub.createProfile({ + to: anotherBidder.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const mirrorerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherBidder).mirror({ + profileId: mirrorerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const mirrorPubId = FIRST_PUB_ID; + // Bidder places his first bid through original publication + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PUB_ID, FIRST_PUB_ID, bidAmount, 0) + ).to.not.be.reverted; + // Bidder's referrer profile ID should be 0, which means no referrer + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + bidder.address + ) + ).to.be.equals(0); + // Another bidder places his first bid through its own mirror publication + bidAmount = bidAmount.add(DEFAULT_MIN_BID_INCREMENT); + await expect( + auctionCollectModule + .connect(anotherBidder) + .bid(mirrorerProfileId, mirrorPubId, bidAmount, 0) + ).to.not.be.reverted; + // Another bidder's referrer profile ID should be his own profile + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + anotherBidder.address + ) + ).to.be.equals(mirrorerProfileId); + // Bidder places his second bid through another bidder's mirror + bidAmount = bidAmount.add(DEFAULT_MIN_BID_INCREMENT); + await expect( + auctionCollectModule.connect(bidder).bid(mirrorerProfileId, mirrorPubId, bidAmount, 0) + ).to.not.be.reverted; + // Bidder's referrer profile ID should still be 0, as referrer is set only through first bid of each bidder + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + bidder.address + ) + ).to.be.equals(0); + }); + }); + }); + + context('Bid with signature', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + }); + + context('Negatives', function () { + it('User should fail to bid if bidder does not match signer', async function () { + const signature = await signBidWithSigMessage({ signer: anotherBidder }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message deadline was exceeded', async function () { + const expiredDeadline = ethers.constants.One; + const signature = await signBidWithSigMessage({ + signer: bidder, + deadline: expiredDeadline, + }); + expect(expiredDeadline.lt(await getTimestamp())).to.be.true; + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('User should fail to bid if signed message had wrong nonce', async function () { + const currentNonce = await auctionCollectModule.nonces(bidder.address); + const invalidNonce = await currentNonce.add(5); + const signature = await signBidWithSigMessage({ signer: bidder, nonce: invalidNonce }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message domain had wrong version', async function () { + const invalidVersion = '0'; + const invalidDomain: Domain = { + name: 'AuctionCollectModule', + version: invalidVersion, + chainId: chainId, + verifyingContract: auctionCollectModule.address, + }; + const signature = await signBidWithSigMessage({ signer: bidder, domain: invalidDomain }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message domain had wrong chain ID', async function () { + const invalidChainId = 69; + expect(chainId).to.not.equals(invalidChainId); + const invalidDomain: Domain = { + name: 'AuctionCollectModule', + version: '1', + chainId: invalidChainId, + verifyingContract: auctionCollectModule.address, + }; + const signature = await signBidWithSigMessage({ signer: bidder, domain: invalidDomain }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message domain had wrong verifying contract', async function () { + const invalidVerifyingContract = ( + await new AuctionCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ) + ).address; + const invalidDomain: Domain = { + name: 'AuctionCollectModule', + version: '1', + chainId: chainId, + verifyingContract: invalidVerifyingContract, + }; + const signature = await signBidWithSigMessage({ signer: bidder, domain: invalidDomain }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message domain had wrong name', async function () { + const invalidName = 'Auction Collect Module'; + const invalidDomain: Domain = { + name: invalidName, + version: '1', + chainId: chainId, + verifyingContract: auctionCollectModule.address, + }; + const signature = await signBidWithSigMessage({ signer: bidder, domain: invalidDomain }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + }); + + it('Funds should be deposited into the contract when a signature-based bid is placed', async function () { + const bidderBalanceBeforeBid = await currency.balanceOf(bidder.address); + const moduleBalanceBeforeBid = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceBeforeBid.isZero()).to.be.true; + const signature = await signBidWithSigMessage({ signer: bidder }); + const tx = auctionCollectModule + .connect(anotherUser) + .bidWithSig(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0, bidder.address, signature); + const txReceipt = await waitForTx(tx); + const txTimestamp = await getTimestamp(); + const endTimestamp = DEFAULT_DURATION.add(txTimestamp); + matchEvent( + txReceipt, + 'BidPlaced', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + 0, + DEFAULT_AMOUNT, + 0, + bidder.address, + endTimestamp, + txTimestamp, + ], + auctionCollectModule + ); + const bidderBalanceAfterBid = await currency.balanceOf(bidder.address); + const moduleBalanceAfterBid = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceAfterBid.eq(DEFAULT_AMOUNT)).to.be.true; + expect(bidderBalanceAfterBid.eq(bidderBalanceBeforeBid.sub(DEFAULT_AMOUNT))).to.be.true; + }); + + it('Funds should be returned to previous winner when a better bid is placed by another bidder', async function () { + const bidderBalanceBeforeBids = await currency.balanceOf(bidder.address); + const anotherBidderBalanceBeforeBids = await currency.balanceOf(anotherBidder.address); + const moduleBalanceBeforeBids = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceBeforeBids.isZero()).to.be.true; + let signature = await signBidWithSigMessage({ signer: bidder }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + 0, + bidder.address, + signature + ) + ).to.not.be.reverted; + const bidderBalanceAfter1stBid = await currency.balanceOf(bidder.address); + const anotherBidderAfter1stBid = await currency.balanceOf(anotherBidder.address); + const moduleBalanceAfter1stBid = await currency.balanceOf(auctionCollectModule.address); + expect(anotherBidderBalanceBeforeBids.eq(anotherBidderAfter1stBid)).to.be.true; + expect(moduleBalanceAfter1stBid.eq(DEFAULT_AMOUNT)).to.be.true; + expect(bidderBalanceAfter1stBid.eq(bidderBalanceBeforeBids.sub(DEFAULT_AMOUNT))).to.be.true; + const secondBidAmount = DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT); + signature = await signBidWithSigMessage({ + signer: anotherBidder, + amount: secondBidAmount, + }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + secondBidAmount, + 0, + anotherBidder.address, + signature + ) + ).to.not.be.reverted; + const bidderBalanceAfterBids = await currency.balanceOf(bidder.address); + const anotherBidderBalanceAfterBids = await currency.balanceOf(anotherBidder.address); + const moduleBalanceAfterBids = await currency.balanceOf(auctionCollectModule.address); + expect(bidderBalanceAfterBids.eq(bidderBalanceAfterBids)).to.be.true; + expect(moduleBalanceAfterBids.eq(secondBidAmount)).to.be.true; + expect( + anotherBidderBalanceAfterBids.eq(anotherBidderBalanceBeforeBids.sub(secondBidAmount)) + ).to.be.true; + }); + + it('Auction should be extended by time set up by publisher in case of a bid placed when less than that time is left', async function () { + const oneMinuteInSeconds = BigNumber.from(60); + const fiveMinutes = oneMinuteInSeconds.mul(5); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ + minTimeAfterBid: fiveMinutes, + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + let signature = await signBidWithSigMessage({ signer: bidder, pubId: pubId }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0, bidder.address, signature) + ).to.not.be.reverted; + let auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId); + expect(auction.endTimestamp.eq(auction.startTimestamp.add(auction.duration))); + const endTimestampAfterFirstBid = auction.endTimestamp; + const secondBidTimestamp = endTimestampAfterFirstBid.sub(oneMinuteInSeconds).toNumber(); + const secondBidAmount = DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT); + await setNextBlockTimestamp(secondBidTimestamp); + signature = await signBidWithSigMessage({ + signer: anotherBidder, + pubId: pubId, + amount: secondBidAmount, + }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig( + FIRST_PROFILE_ID, + pubId, + secondBidAmount, + 0, + anotherBidder.address, + signature + ) + ).to.not.be.reverted; + auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId); + expect(auction.endTimestamp.eq(auction.minTimeAfterBid + secondBidTimestamp)).to.be.true; + }); + + it('Referrer profile ID should be set properly and only at first bid of each one', async function () { + let bidAmount = DEFAULT_AMOUNT; + await lensHub.createProfile({ + to: anotherBidder.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const mirrorerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherBidder).mirror({ + profileId: mirrorerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const mirrorPubId = FIRST_PUB_ID; + // Bidder places his first bid through original publication + let signature = await signBidWithSigMessage({ signer: bidder, amount: bidAmount }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig(FIRST_PUB_ID, FIRST_PUB_ID, bidAmount, 0, bidder.address, signature) + ).to.not.be.reverted; + // Bidder's referrer profile ID should be 0, which means no referrer + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + bidder.address + ) + ).to.be.equals(0); + // Another bidder places his first bid through its own mirror publication + bidAmount = bidAmount.add(DEFAULT_MIN_BID_INCREMENT); + signature = await signBidWithSigMessage({ + signer: anotherBidder, + profileId: mirrorerProfileId, + pubId: mirrorPubId, + amount: bidAmount, + }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig( + mirrorerProfileId, + mirrorPubId, + bidAmount, + 0, + anotherBidder.address, + signature + ) + ).to.not.be.reverted; + // Another bidder's referrer profile ID should be his own profile + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + anotherBidder.address + ) + ).to.be.equals(mirrorerProfileId); + // Bidder places his second bid through another bidder's mirror + bidAmount = bidAmount.add(DEFAULT_MIN_BID_INCREMENT); + signature = await signBidWithSigMessage({ + signer: bidder, + profileId: mirrorerProfileId, + pubId: mirrorPubId, + amount: bidAmount, + }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig(mirrorerProfileId, mirrorPubId, bidAmount, 0, bidder.address, signature) + ).to.not.be.reverted; + // Bidder's referrer profile ID should still be 0, as referrer is set only through first bid of each bidder + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + bidder.address + ) + ).to.be.equals(0); + }); + }); + }); + + context('Process collect and fees', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + }); + + context('Negatives', function () { + it('Process collect call should fail if caller is not the hub', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .processCollect(0, bidder.address, FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.NOT_HUB); + }); + + it('User should fail to process collect over unexistent publication', async function () { + const unexistentPubId = 69; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, unexistentPubId, []) + ).to.be.revertedWith(ERRORS.PUBLICATION_DOES_NOT_EXIST); + }); + + it('User should fail to process collect over existent yet unavailable auction', async function () { + const futureTimestamp = (await getTimestamp()) + ONE_DAY_IN_SECONDS; + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ + availableSinceTimestamp: futureTimestamp, + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, pubId, []) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to process collect over existent available but unstarted auction', async function () { + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.ONGOING_AUCTION); + }); + + it('User should fail to process collect over active auction', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.ONGOING_AUCTION); + }); + + it('User should fail to process collect if he is not the auction winner', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + expect(auction.winner).to.be.equals(bidder.address); + expect(bidder.address).to.not.be.equal(anotherUser.address); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process collect if collects through a publication that makes lens hub pass a wrong referrer profile ID', async function () { + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const mirrorPubId = FIRST_PUB_ID; + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, mirrorPubId, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + expect(auction.winner).to.be.equals(bidder.address); + const referrerProfileIdOfWinner = await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + auction.winner + ); + expect(referrerProfileIdOfWinner).to.be.equals(referrerProfileId); + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process collect if publication was already collected', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + expect(auction.collected).to.be.true; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.COLLECT_ALREADY_PROCESSED); + }); + + it('User should fail to process collect if is only for followers and and he is not following the publication owner', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect(lensHub.connect(bidder).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await simulateAuctionEnd({ + pubId: pubId, + }); + const followNftAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNft = await FollowNFT__factory.connect(followNftAddress, bidder); + await expect( + followNft.transferFrom(bidder.address, anotherUser.address, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await expect( + lensHub + .connect(bidder) + .collect(FIRST_PROFILE_ID, pubId, abiCoder.encode(['uint256'], [FIRST_FOLLOW_NFT_ID])) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to process collect if is only for followers and and he followed publication owner after auction started', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect(lensHub.connect(bidder).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await simulateAuctionEnd({ + pubId: pubId, + }); + const followNftAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNft = await FollowNFT__factory.connect(followNftAddress, bidder); + await expect(followNft.burn(FIRST_FOLLOW_NFT_ID)).to.not.be.reverted; + await expect(lensHub.connect(bidder).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const newFollowNftId = FIRST_FOLLOW_NFT_ID + 1; + await expect( + lensHub + .connect(bidder) + .collect(FIRST_PROFILE_ID, pubId, abiCoder.encode(['uint256'], [newFollowNftId])) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to process collect if auction was open for everyone and he passed any arbitrary data', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const dataThatShouldNotBePassed = abiCoder.encode(['uint256'], [FIRST_FOLLOW_NFT_ID]); + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, dataThatShouldNotBePassed) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process fees over unexistent publication', async function () { + const unexistentPubId = 69; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, unexistentPubId) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to process fees over publication that uses another collect module', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, pubId) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to process fees over unstarted auction', async function () { + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.be.revertedWith(ERRORS.ONGOING_AUCTION); + }); + + it('User should fail to process fees over active auction', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.be.revertedWith(ERRORS.ONGOING_AUCTION); + }); + + it('User should fail to process fees over auction that already processed fees through process collect call', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const auctionBeforeCollect = await auctionCollectModule.getAuctionData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ); + expect(auctionBeforeCollect.collected).to.be.false; + expect(auctionBeforeCollect.feeProcessed).to.be.false; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const auctionAfterCollect = await auctionCollectModule.getAuctionData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ); + expect(auctionAfterCollect.collected).to.be.true; + expect(auctionAfterCollect.feeProcessed).to.be.true; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.be.revertedWith(ERRORS.FEE_ALREADY_PROCESSED); + }); + + it('User should fail to process fees over auction that already processed fee through process fees call', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const auctionBeforeCollectFee = await auctionCollectModule.getAuctionData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ); + expect(auctionBeforeCollectFee.collected).to.be.false; + expect(auctionBeforeCollectFee.feeProcessed).to.be.false; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.not.be.reverted; + const auctionAfterCollectFee = await auctionCollectModule.getAuctionData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ); + expect(auctionAfterCollectFee.collected).to.be.false; + expect(auctionAfterCollectFee.feeProcessed).to.be.true; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.be.revertedWith(ERRORS.FEE_ALREADY_PROCESSED); + }); + }); + + context('Scenarios', function () { + it('User should win and collect an only followers auction borrowing different follow NFTs through the entire process', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + // Two different users follow publisher profile before the auction starts + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + await expect( + lensHub.connect(thirdUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const secondFollowNftId = FIRST_FOLLOW_NFT_ID + 1; + const followNftAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNft = await FollowNFT__factory.connect(followNftAddress, bidder); + // We verify the users has a follow NFT now but the bidder does not + expect((await followNft.balanceOf(bidder.address)).isZero()).to.be.true; + expect((await followNft.balanceOf(anotherUser.address)).isZero()).to.be.false; + expect((await followNft.balanceOf(thirdUser.address)).isZero()).to.be.false; + // Bidder takes follow NFT from anotherUser, places a bid and return it back + await expect( + followNft + .connect(anotherUser) + .transferFrom(anotherUser.address, bidder.address, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await expect( + followNft + .connect(bidder) + .transferFrom(bidder.address, anotherUser.address, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + // Auction ends, bidder becomes the winner + await simulateAuctionEnd({ + pubId: pubId, + }); + // Bidder takes follow NFT from thirdUser to be able to collect + await expect( + followNft + .connect(thirdUser) + .transferFrom(thirdUser.address, bidder.address, secondFollowNftId) + ).to.not.be.reverted; + await expect( + lensHub + .connect(bidder) + .collect(FIRST_PROFILE_ID, pubId, abiCoder.encode(['uint256'], [secondFollowNftId])) + ).to.not.be.reverted; + }); + + it('Anoyone should succeed to trigger collect fees processing after auction finishes before the winner collects', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const treasuryBalanceBeforeFees = await currency.balanceOf(treasury.address); + const recipientBalanceBeforeFees = await currency.balanceOf(feeRecipient.address); + const tx = auctionCollectModule + .connect(anotherUser) + .processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID); + const txReceipt = await waitForTx(tx); + matchEvent( + txReceipt, + 'FeeProcessed', + [FIRST_PROFILE_ID, FIRST_PUB_ID, await getTimestamp()], + auctionCollectModule + ); + const treasuryBalanceAfterFees = await currency.balanceOf(treasury.address); + const recipientBalanceAfterFees = await currency.balanceOf(feeRecipient.address); + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedTreausyFee = DEFAULT_AMOUNT.mul(TREASURY_FEE_BPS).div(BPS_MAX); + const expectedRecipientFee = DEFAULT_AMOUNT.sub(expectedTreausyFee); + expect(treasuryBalanceBeforeFees.isZero()).to.be.true; + expect(recipientBalanceBeforeFees.isZero()).to.be.true; + expect(treasuryBalanceAfterFees).to.be.equals(expectedTreausyFee); + expect(recipientBalanceAfterFees).to.be.equals(expectedRecipientFee); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceAfterFees); + expect(recipientBalanceAfterCollect).to.be.equals(recipientBalanceAfterFees); + }); + + it('Owner of referrer profile should receive a cut of the collect fees', async function () { + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Creates referrer profile who mirrors publication + await lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Bidder places a bid through mirrored publication + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + // Auction finishes + await simulateAuctionEnd({}); + // Collects through same mirrored publication as it is required + await expect( + lensHub.connect(bidder).collect(referrerProfileId, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedTreasuryFee = DEFAULT_AMOUNT.mul(TREASURY_FEE_BPS).div(BPS_MAX); + const expectedScaledAmount = DEFAULT_AMOUNT.sub(expectedTreasuryFee); + const expectedReferralFee = expectedScaledAmount.mul(REFERRAL_FEE_BPS).div(BPS_MAX); + const expectedRecipientFee = expectedScaledAmount.sub(expectedReferralFee); + expect(treasuryBalanceAfterCollect).to.be.equals( + treasuryBalanceBeforeCollect.add(expectedTreasuryFee) + ); + expect(referrerBalanceAfterCollect).to.be.equals( + referrerBalanceBeforeCollect.add(expectedReferralFee) + ); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedRecipientFee) + ); + }); + + it('Owner of referrer profile should not receive collect fees if referrer fee was set to zero', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ referralFee: 0 }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Creates referrer profile who mirrors publication + await lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: pubId, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Bidder places a bid through mirrored publication + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + // Auction finishes + await simulateAuctionEnd({ pubId: pubId }); + // Collects through same mirrored publication as it is required + await expect( + lensHub.connect(bidder).collect(referrerProfileId, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedTreasuryFee = DEFAULT_AMOUNT.mul(TREASURY_FEE_BPS).div(BPS_MAX); + const expectedScaledAmount = DEFAULT_AMOUNT.sub(expectedTreasuryFee); + expect(treasuryBalanceAfterCollect).to.be.equals( + treasuryBalanceBeforeCollect.add(expectedTreasuryFee) + ); + expect(referrerBalanceAfterCollect).to.be.equals(referrerBalanceBeforeCollect); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedScaledAmount) + ); + }); + + it('Fee recipient should receive all collect fees when publication is collected through original publication and treasury fee was set to zero', async function () { + await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + await expect( + lensHub.connect(bidder).collect(FIRST_PUB_ID, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceBeforeCollect); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(DEFAULT_AMOUNT) + ); + }); + + it('Fee recipient and referrer profile owners should share the entire fees between them if treasury feet was set to zero', async function () { + await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Creates referrer profile who mirrors publication + await lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Bidder places a bid through mirrored publication + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + // Auction finishes + await simulateAuctionEnd({}); + // Collects through same mirrored publication as it is required + await expect( + lensHub.connect(bidder).collect(referrerProfileId, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedReferralFee = DEFAULT_AMOUNT.mul(REFERRAL_FEE_BPS).div(BPS_MAX); + const expectedRecipientFee = DEFAULT_AMOUNT.sub(expectedReferralFee); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceBeforeCollect); + expect(referrerBalanceAfterCollect).to.be.equals( + referrerBalanceBeforeCollect.add(expectedReferralFee) + ); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedRecipientFee) + ); + expect( + recipientBalanceAfterCollect + .sub(recipientBalanceBeforeCollect) + .add(referrerBalanceAfterCollect) + .sub(referrerBalanceBeforeCollect) + ).to.be.equals(DEFAULT_AMOUNT); + }); + + it('Publication owner should get the entire collect fees if referrer and treasury fees were set to zero', async function () { + await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted; + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ referralFee: 0 }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Creates referrer profile who mirrors publication + await lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: pubId, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Bidder places a bid through mirrored publication + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + // Auction finishes + await simulateAuctionEnd({ pubId: pubId }); + // Collects through same mirrored publication as it is required + await expect( + lensHub.connect(bidder).collect(referrerProfileId, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceBeforeCollect); + expect(referrerBalanceAfterCollect).to.be.equals(referrerBalanceBeforeCollect); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(DEFAULT_AMOUNT) + ); + }); + }); + }); +}); diff --git a/lens-protocol/modules/test/modules/collect/old-partial-carbon-retirement-collect-module.ts b/lens-protocol/modules/test/modules/collect/old-partial-carbon-retirement-collect-module.ts new file mode 100644 index 0000000..8cc1acd --- /dev/null +++ b/lens-protocol/modules/test/modules/collect/old-partial-carbon-retirement-collect-module.ts @@ -0,0 +1,1737 @@ +import { BigNumber, BigNumberish } from '@ethersproject/bignumber'; +import { parseEther } from '@ethersproject/units'; +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { AuctionCollectModule__factory, FollowNFT__factory } from '../../../typechain'; +import { ERRORS } from '../../helpers/errors'; +import { + abiCoder, + auctionCollectModule, + BPS_MAX, + chainId, + currency, + feeRecipient, + FIRST_PROFILE_ID, + FIRST_PUB_ID, + freeCollectModule, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_URI, + moduleGlobals, + anotherUser, + REFERRAL_FEE_BPS, + user, + FIRST_FOLLOW_NFT_ID, + deployer, + thirdUser, + treasury, + TREASURY_FEE_BPS, + governance, + DEFAULT_AMOUNT, +} from '../../__setup.spec'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { publisher } from '../../__setup.spec'; +import { getTimestamp, matchEvent, setNextBlockTimestamp, waitForTx } from '../../helpers/utils'; +import { signBidWithSigMessage } from '../../helpers/signatures/modules/collect/auction-collect-module'; +import { Domain } from '../../helpers/signatures/utils'; + +export let BID_WITH_SIG_DOMAIN: Domain; + +makeSuiteCleanRoom('AuctionCollectModule', function () { + const ONE_DAY_IN_SECONDS = BigNumber.from(24 * 3600); + const TEN_MINUTES_IN_SECONDS = BigNumber.from(10 * 60); + const DEFAULT_RESERVE_PRICE = parseEther('1'); + const DEFAULT_MIN_TIME_AFTER_BID = TEN_MINUTES_IN_SECONDS; + const DEFAULT_MIN_BID_INCREMENT = parseEther('0.1'); + const DEFAULT_DURATION = ONE_DAY_IN_SECONDS; + let bidder: SignerWithAddress; + let anotherBidder: SignerWithAddress; + + interface AuctionCollectModuleInitData { + availableSinceTimestamp?: BigNumber; + duration?: BigNumber; + minTimeAfterBid?: BigNumber; + reservePrice?: BigNumber; + minBidIncrement?: BigNumber; + referralFee?: number; + feeCurrency?: string; + recipient?: string; + onlyFollowers?: boolean; + } + + async function getAuctionCollectModuleInitData({ + availableSinceTimestamp = ethers.constants.Zero, + duration = DEFAULT_DURATION, + minTimeAfterBid = DEFAULT_MIN_TIME_AFTER_BID, + reservePrice = DEFAULT_RESERVE_PRICE, + minBidIncrement = DEFAULT_MIN_BID_INCREMENT, + referralFee = REFERRAL_FEE_BPS, + feeCurrency = currency.address, + recipient = feeRecipient.address, + onlyFollowers = false, + }: AuctionCollectModuleInitData): Promise { + return abiCoder.encode( + ['uint64', 'uint32', 'uint32', 'uint256', 'uint256', 'uint16', 'address', 'address', 'bool'], + [ + availableSinceTimestamp, + duration, + minTimeAfterBid, + reservePrice, + minBidIncrement, + referralFee, + feeCurrency, + recipient, + onlyFollowers, + ] + ); + } + + interface AuctionEndSimulationData { + profileId?: BigNumberish; + pubId?: BigNumberish; + secondsToBeElapsedAfterEnd?: BigNumberish; + } + + async function simulateAuctionEnd({ + profileId = FIRST_PROFILE_ID, + pubId = FIRST_PUB_ID, + secondsToBeElapsedAfterEnd = 1, + }: AuctionEndSimulationData) { + const endTimestamp = (await auctionCollectModule.getAuctionData(profileId, pubId)).endTimestamp; + setNextBlockTimestamp(endTimestamp.add(secondsToBeElapsedAfterEnd).toNumber()); + } + + interface MintAndApproveCurrency { + owner?: SignerWithAddress; + spender?: string; + amountToMint?: BigNumberish; + amountToApprove?: BigNumberish; + } + + async function mintAndApproveCurrency({ + owner = bidder, + spender = auctionCollectModule.address, + amountToMint = parseEther('100000'), + amountToApprove = ethers.constants.MaxUint256, + }: MintAndApproveCurrency) { + await currency.connect(owner).mint(owner.address, amountToMint); + await currency.connect(owner).approve(spender, amountToApprove); + } + + beforeEach(async function () { + BID_WITH_SIG_DOMAIN = { + name: 'AuctionCollectModule', + version: '1', + chainId: chainId, + verifyingContract: auctionCollectModule.address, + }; + bidder = user; + anotherBidder = anotherUser; + await expect( + lensHub.createProfile({ + to: publisher.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Publication creation', function () { + context('Negatives', function () { + it('User should fail to post setting zero duration', async function () { + const collectModuleInitData = await getAuctionCollectModuleInitData({ + duration: ethers.constants.Zero, + minTimeAfterBid: ethers.constants.Zero, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('User should fail to post setting a duration less than min time after bid', async function () { + const duration = ethers.constants.One; + expect(duration.lt(DEFAULT_MIN_TIME_AFTER_BID)).to.be.true; + const collectModuleInitData = await getAuctionCollectModuleInitData({ + duration: duration, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('User should fail to post using unwhitelisted currency', async function () { + const unwhitelistedCurrency = ethers.constants.AddressZero; + expect(await moduleGlobals.isCurrencyWhitelisted(unwhitelistedCurrency)).to.be.false; + const collectModuleInitData = await getAuctionCollectModuleInitData({ + feeCurrency: unwhitelistedCurrency, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('User should fail to post using referral fee greater than max BPS', async function () { + const referralFee = BPS_MAX + 1; + expect(referralFee).to.be.greaterThan(BPS_MAX); + const collectModuleInitData = await getAuctionCollectModuleInitData({ + referralFee: referralFee, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + }); + + context('Scenarios', function () { + it('User should succeed to create a publication when all parameters are valid and tx should emit expected event', async function () { + const collectModuleInitData = await getAuctionCollectModuleInitData({}); + const tx = lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }); + const txReceipt = await waitForTx(tx); + matchEvent( + txReceipt, + 'AuctionCreated', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + ethers.constants.Zero, + DEFAULT_DURATION, + DEFAULT_MIN_TIME_AFTER_BID, + DEFAULT_RESERVE_PRICE, + DEFAULT_MIN_BID_INCREMENT, + REFERRAL_FEE_BPS, + currency.address, + feeRecipient.address, + false, + ], + auctionCollectModule + ); + }); + + it('User should succeed to create a publication that burns the fees', async function () { + const collectModuleInitData = await getAuctionCollectModuleInitData({ + recipient: ethers.constants.AddressZero, + }); + const tx = lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }); + const txReceipt = await waitForTx(tx); + matchEvent( + txReceipt, + 'AuctionCreated', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + ethers.constants.Zero, + DEFAULT_DURATION, + DEFAULT_MIN_TIME_AFTER_BID, + DEFAULT_RESERVE_PRICE, + DEFAULT_MIN_BID_INCREMENT, + REFERRAL_FEE_BPS, + currency.address, + ethers.constants.AddressZero, + false, + ], + auctionCollectModule + ); + }); + }); + }); + + context('Bid', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('User should fail to bid for an unexistent publication', async function () { + const unexistentPubId = 69; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, unexistentPubId, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.PUBLICATION_DOES_NOT_EXIST); + }); + + it('User should fail to bid if the publication uses another collect module', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to bid if auction is not available yet', async function () { + const currentTimestamp = BigNumber.from(await getTimestamp()); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ + availableSinceTimestamp: currentTimestamp.add(ONE_DAY_IN_SECONDS), + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + const availableSinceTimestamp = ( + await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId) + ).availableSinceTimestamp; + expect(availableSinceTimestamp.gt(currentTimestamp)).to.be.true; + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to bid if auction has already ended', async function () { + let auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + let currentTimestamp = BigNumber.from(await getTimestamp()); + expect(currentTimestamp.gt(auction.availableSinceTimestamp)).to.be.true; + await mintAndApproveCurrency({}); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + expect(auction.startTimestamp.gte(currentTimestamp)).to.be.true; + await simulateAuctionEnd({}); + + // The tx below is just a dummy tx that does not affect the context of the test and, as a tx is needed to + // update the block timestamp, being able to verify the precondition of block.timestamp > auction.endTimestamp + // before doing the bid call. + lensHub.connect(publisher).setDefaultProfile(FIRST_PROFILE_ID); + + auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + currentTimestamp = BigNumber.from(await getTimestamp()); + expect(currentTimestamp.gt(auction.endTimestamp)).to.be.true; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT), 0) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to bid if does not have enough balance', async function () { + await mintAndApproveCurrency({ amountToMint: 0 }); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.ERC20_TRANSFER_EXCEEDS_BALANCE); + }); + + it('User should fail to bid if does not have enough allowance', async function () { + await mintAndApproveCurrency({ amountToApprove: 0 }); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.ERC20_INSUFFICIENT_ALLOWANCE); + }); + + it('User should fail to bid if placing the bid that starts the auction but it is below reserve price', async function () { + const reservePrice = ( + await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).reservePrice; + const bidAmountBelowReservePrice = parseEther('0.01'); + expect(reservePrice.gt(bidAmountBelowReservePrice)).to.be.true; + await mintAndApproveCurrency({}); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, bidAmountBelowReservePrice, 0) + ).to.be.revertedWith(ERRORS.INSUFFICIENT_BID_AMOUNT); + }); + + it('User should fail to bid if auction already started but bid does not comply min increment requirement', async function () { + await mintAndApproveCurrency({}); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.be.not.be.reverted; + const auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + const bidAmountWithoutEnoughIncrement = DEFAULT_AMOUNT.add(1); + expect(bidAmountWithoutEnoughIncrement.gt(DEFAULT_AMOUNT)).to.be.true; + expect( + bidAmountWithoutEnoughIncrement.sub(DEFAULT_AMOUNT).lt(auction.minBidIncrement) + ).to.be.true; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, bidAmountWithoutEnoughIncrement, 0) + ).to.be.revertedWith(ERRORS.INSUFFICIENT_BID_AMOUNT); + }); + + it('User should fail to bid if auction is only for followers and he is not following the publication owner', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + expect( + (await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId)).onlyFollowers + ).to.be.true; + await mintAndApproveCurrency({}); + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to bid if auction is only for followers and he followed publication owner after auction started', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + expect( + (await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId)).onlyFollowers + ).to.be.true; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + await expect( + lensHub.connect(anotherBidder).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + await expect( + auctionCollectModule + .connect(anotherBidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await expect(lensHub.connect(bidder).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const followNftAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const bidderFollowNftBalance = await FollowNFT__factory.connect( + followNftAddress, + bidder + ).balanceOf(bidder.address); + expect(bidderFollowNftBalance.gt(ethers.constants.Zero)).to.be.true; + await expect( + auctionCollectModule + .connect(bidder) + .bid( + FIRST_PROFILE_ID, + pubId, + DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT), + FIRST_FOLLOW_NFT_ID + 1 + ) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + }); + + context('Scenarios', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + }); + + it('Funds should be deposited into the contract when a bid is placed', async function () { + const bidderBalanceBeforeBid = await currency.balanceOf(bidder.address); + const moduleBalanceBeforeBid = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceBeforeBid.isZero()).to.be.true; + const tx = auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0); + const txReceipt = await waitForTx(tx); + const txTimestamp = await getTimestamp(); + const endTimestamp = DEFAULT_DURATION.add(txTimestamp); + matchEvent( + txReceipt, + 'BidPlaced', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + 0, + DEFAULT_AMOUNT, + 0, + bidder.address, + endTimestamp, + txTimestamp, + ], + auctionCollectModule + ); + const bidderBalanceAfterBid = await currency.balanceOf(bidder.address); + const moduleBalanceAfterBid = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceAfterBid.eq(DEFAULT_AMOUNT)).to.be.true; + expect(bidderBalanceAfterBid.eq(bidderBalanceBeforeBid.sub(DEFAULT_AMOUNT))).to.be.true; + }); + + it('Funds should be returned to previous winner when a better bid is placed by another bidder', async function () { + const bidderBalanceBeforeBids = await currency.balanceOf(bidder.address); + const anotherBidderBalanceBeforeBids = await currency.balanceOf(anotherBidder.address); + const moduleBalanceBeforeBids = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceBeforeBids.isZero()).to.be.true; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + const bidderBalanceAfter1stBid = await currency.balanceOf(bidder.address); + const anotherBidderAfter1stBid = await currency.balanceOf(anotherBidder.address); + const moduleBalanceAfter1stBid = await currency.balanceOf(auctionCollectModule.address); + expect(anotherBidderBalanceBeforeBids.eq(anotherBidderAfter1stBid)).to.be.true; + expect(moduleBalanceAfter1stBid.eq(DEFAULT_AMOUNT)).to.be.true; + expect(bidderBalanceAfter1stBid.eq(bidderBalanceBeforeBids.sub(DEFAULT_AMOUNT))).to.be.true; + const secondBidAmount = DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT); + await expect( + auctionCollectModule + .connect(anotherBidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, secondBidAmount, 0) + ).to.not.be.reverted; + const bidderBalanceAfterBids = await currency.balanceOf(bidder.address); + const anotherBidderBalanceAfterBids = await currency.balanceOf(anotherBidder.address); + const moduleBalanceAfterBids = await currency.balanceOf(auctionCollectModule.address); + expect(bidderBalanceAfterBids.eq(bidderBalanceAfterBids)).to.be.true; + expect(moduleBalanceAfterBids.eq(secondBidAmount)).to.be.true; + expect( + anotherBidderBalanceAfterBids.eq(anotherBidderBalanceBeforeBids.sub(secondBidAmount)) + ).to.be.true; + }); + + it('Auction should be extended by time set up by publisher in case of a bid placed when less than that time is left', async function () { + const oneMinuteInSeconds = BigNumber.from(60); + const fiveMinutes = oneMinuteInSeconds.mul(5); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ + minTimeAfterBid: fiveMinutes, + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + let auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId); + expect(auction.endTimestamp.eq(auction.startTimestamp.add(auction.duration))); + const endTimestampAfterFirstBid = auction.endTimestamp; + const secondBidTimestamp = endTimestampAfterFirstBid.sub(oneMinuteInSeconds).toNumber(); + await setNextBlockTimestamp(secondBidTimestamp); + await expect( + auctionCollectModule + .connect(anotherBidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT), 0) + ).to.not.be.reverted; + auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId); + expect(auction.endTimestamp.eq(auction.minTimeAfterBid + secondBidTimestamp)).to.be.true; + }); + + it('Referrer profile ID should be set properly and only at first bid of each one', async function () { + let bidAmount = DEFAULT_AMOUNT; + await lensHub.createProfile({ + to: anotherBidder.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const mirrorerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherBidder).mirror({ + profileId: mirrorerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const mirrorPubId = FIRST_PUB_ID; + // Bidder places his first bid through original publication + await expect( + auctionCollectModule.connect(bidder).bid(FIRST_PUB_ID, FIRST_PUB_ID, bidAmount, 0) + ).to.not.be.reverted; + // Bidder's referrer profile ID should be 0, which means no referrer + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + bidder.address + ) + ).to.be.equals(0); + // Another bidder places his first bid through its own mirror publication + bidAmount = bidAmount.add(DEFAULT_MIN_BID_INCREMENT); + await expect( + auctionCollectModule + .connect(anotherBidder) + .bid(mirrorerProfileId, mirrorPubId, bidAmount, 0) + ).to.not.be.reverted; + // Another bidder's referrer profile ID should be his own profile + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + anotherBidder.address + ) + ).to.be.equals(mirrorerProfileId); + // Bidder places his second bid through another bidder's mirror + bidAmount = bidAmount.add(DEFAULT_MIN_BID_INCREMENT); + await expect( + auctionCollectModule.connect(bidder).bid(mirrorerProfileId, mirrorPubId, bidAmount, 0) + ).to.not.be.reverted; + // Bidder's referrer profile ID should still be 0, as referrer is set only through first bid of each bidder + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + bidder.address + ) + ).to.be.equals(0); + }); + }); + }); + + context('Bid with signature', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + }); + + context('Negatives', function () { + it('User should fail to bid if bidder does not match signer', async function () { + const signature = await signBidWithSigMessage({ signer: anotherBidder }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message deadline was exceeded', async function () { + const expiredDeadline = ethers.constants.One; + const signature = await signBidWithSigMessage({ + signer: bidder, + deadline: expiredDeadline, + }); + expect(expiredDeadline.lt(await getTimestamp())).to.be.true; + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('User should fail to bid if signed message had wrong nonce', async function () { + const currentNonce = await auctionCollectModule.nonces(bidder.address); + const invalidNonce = await currentNonce.add(5); + const signature = await signBidWithSigMessage({ signer: bidder, nonce: invalidNonce }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message domain had wrong version', async function () { + const invalidVersion = '0'; + const invalidDomain: Domain = { + name: 'AuctionCollectModule', + version: invalidVersion, + chainId: chainId, + verifyingContract: auctionCollectModule.address, + }; + const signature = await signBidWithSigMessage({ signer: bidder, domain: invalidDomain }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message domain had wrong chain ID', async function () { + const invalidChainId = 69; + expect(chainId).to.not.equals(invalidChainId); + const invalidDomain: Domain = { + name: 'AuctionCollectModule', + version: '1', + chainId: invalidChainId, + verifyingContract: auctionCollectModule.address, + }; + const signature = await signBidWithSigMessage({ signer: bidder, domain: invalidDomain }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message domain had wrong verifying contract', async function () { + const invalidVerifyingContract = ( + await new AuctionCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ) + ).address; + const invalidDomain: Domain = { + name: 'AuctionCollectModule', + version: '1', + chainId: chainId, + verifyingContract: invalidVerifyingContract, + }; + const signature = await signBidWithSigMessage({ signer: bidder, domain: invalidDomain }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to bid if signed message domain had wrong name', async function () { + const invalidName = 'Auction Collect Module'; + const invalidDomain: Domain = { + name: invalidName, + version: '1', + chainId: chainId, + verifyingContract: auctionCollectModule.address, + }; + const signature = await signBidWithSigMessage({ signer: bidder, domain: invalidDomain }); + await expect( + auctionCollectModule.bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + FIRST_FOLLOW_NFT_ID, + bidder.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + }); + + context('Scenarios', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + }); + + it('Funds should be deposited into the contract when a signature-based bid is placed', async function () { + const bidderBalanceBeforeBid = await currency.balanceOf(bidder.address); + const moduleBalanceBeforeBid = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceBeforeBid.isZero()).to.be.true; + const signature = await signBidWithSigMessage({ signer: bidder }); + const tx = auctionCollectModule + .connect(anotherUser) + .bidWithSig(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0, bidder.address, signature); + const txReceipt = await waitForTx(tx); + const txTimestamp = await getTimestamp(); + const endTimestamp = DEFAULT_DURATION.add(txTimestamp); + matchEvent( + txReceipt, + 'BidPlaced', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + 0, + DEFAULT_AMOUNT, + 0, + bidder.address, + endTimestamp, + txTimestamp, + ], + auctionCollectModule + ); + const bidderBalanceAfterBid = await currency.balanceOf(bidder.address); + const moduleBalanceAfterBid = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceAfterBid.eq(DEFAULT_AMOUNT)).to.be.true; + expect(bidderBalanceAfterBid.eq(bidderBalanceBeforeBid.sub(DEFAULT_AMOUNT))).to.be.true; + }); + + it('Funds should be returned to previous winner when a better bid is placed by another bidder', async function () { + const bidderBalanceBeforeBids = await currency.balanceOf(bidder.address); + const anotherBidderBalanceBeforeBids = await currency.balanceOf(anotherBidder.address); + const moduleBalanceBeforeBids = await currency.balanceOf(auctionCollectModule.address); + expect(moduleBalanceBeforeBids.isZero()).to.be.true; + let signature = await signBidWithSigMessage({ signer: bidder }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + 0, + bidder.address, + signature + ) + ).to.not.be.reverted; + const bidderBalanceAfter1stBid = await currency.balanceOf(bidder.address); + const anotherBidderAfter1stBid = await currency.balanceOf(anotherBidder.address); + const moduleBalanceAfter1stBid = await currency.balanceOf(auctionCollectModule.address); + expect(anotherBidderBalanceBeforeBids.eq(anotherBidderAfter1stBid)).to.be.true; + expect(moduleBalanceAfter1stBid.eq(DEFAULT_AMOUNT)).to.be.true; + expect(bidderBalanceAfter1stBid.eq(bidderBalanceBeforeBids.sub(DEFAULT_AMOUNT))).to.be.true; + const secondBidAmount = DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT); + signature = await signBidWithSigMessage({ + signer: anotherBidder, + amount: secondBidAmount, + }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + secondBidAmount, + 0, + anotherBidder.address, + signature + ) + ).to.not.be.reverted; + const bidderBalanceAfterBids = await currency.balanceOf(bidder.address); + const anotherBidderBalanceAfterBids = await currency.balanceOf(anotherBidder.address); + const moduleBalanceAfterBids = await currency.balanceOf(auctionCollectModule.address); + expect(bidderBalanceAfterBids.eq(bidderBalanceAfterBids)).to.be.true; + expect(moduleBalanceAfterBids.eq(secondBidAmount)).to.be.true; + expect( + anotherBidderBalanceAfterBids.eq(anotherBidderBalanceBeforeBids.sub(secondBidAmount)) + ).to.be.true; + }); + + it('Auction should be extended by time set up by publisher in case of a bid placed when less than that time is left', async function () { + const oneMinuteInSeconds = BigNumber.from(60); + const fiveMinutes = oneMinuteInSeconds.mul(5); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ + minTimeAfterBid: fiveMinutes, + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + let signature = await signBidWithSigMessage({ signer: bidder, pubId: pubId }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, 0, bidder.address, signature) + ).to.not.be.reverted; + let auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId); + expect(auction.endTimestamp.eq(auction.startTimestamp.add(auction.duration))); + const endTimestampAfterFirstBid = auction.endTimestamp; + const secondBidTimestamp = endTimestampAfterFirstBid.sub(oneMinuteInSeconds).toNumber(); + const secondBidAmount = DEFAULT_AMOUNT.add(DEFAULT_MIN_BID_INCREMENT); + await setNextBlockTimestamp(secondBidTimestamp); + signature = await signBidWithSigMessage({ + signer: anotherBidder, + pubId: pubId, + amount: secondBidAmount, + }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig( + FIRST_PROFILE_ID, + pubId, + secondBidAmount, + 0, + anotherBidder.address, + signature + ) + ).to.not.be.reverted; + auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, pubId); + expect(auction.endTimestamp.eq(auction.minTimeAfterBid + secondBidTimestamp)).to.be.true; + }); + + it('Referrer profile ID should be set properly and only at first bid of each one', async function () { + let bidAmount = DEFAULT_AMOUNT; + await lensHub.createProfile({ + to: anotherBidder.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const mirrorerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherBidder).mirror({ + profileId: mirrorerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const mirrorPubId = FIRST_PUB_ID; + // Bidder places his first bid through original publication + let signature = await signBidWithSigMessage({ signer: bidder, amount: bidAmount }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig(FIRST_PUB_ID, FIRST_PUB_ID, bidAmount, 0, bidder.address, signature) + ).to.not.be.reverted; + // Bidder's referrer profile ID should be 0, which means no referrer + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + bidder.address + ) + ).to.be.equals(0); + // Another bidder places his first bid through its own mirror publication + bidAmount = bidAmount.add(DEFAULT_MIN_BID_INCREMENT); + signature = await signBidWithSigMessage({ + signer: anotherBidder, + profileId: mirrorerProfileId, + pubId: mirrorPubId, + amount: bidAmount, + }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig( + mirrorerProfileId, + mirrorPubId, + bidAmount, + 0, + anotherBidder.address, + signature + ) + ).to.not.be.reverted; + // Another bidder's referrer profile ID should be his own profile + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + anotherBidder.address + ) + ).to.be.equals(mirrorerProfileId); + // Bidder places his second bid through another bidder's mirror + bidAmount = bidAmount.add(DEFAULT_MIN_BID_INCREMENT); + signature = await signBidWithSigMessage({ + signer: bidder, + profileId: mirrorerProfileId, + pubId: mirrorPubId, + amount: bidAmount, + }); + await expect( + auctionCollectModule + .connect(anotherUser) + .bidWithSig(mirrorerProfileId, mirrorPubId, bidAmount, 0, bidder.address, signature) + ).to.not.be.reverted; + // Bidder's referrer profile ID should still be 0, as referrer is set only through first bid of each bidder + expect( + await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + bidder.address + ) + ).to.be.equals(0); + }); + }); + }); + + context('Process collect and fees', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({}); + await mintAndApproveCurrency({ owner: anotherBidder }); + }); + + context('Negatives', function () { + it('Process collect call should fail if caller is not the hub', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .processCollect(0, bidder.address, FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.NOT_HUB); + }); + + it('User should fail to process collect over unexistent publication', async function () { + const unexistentPubId = 69; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, unexistentPubId, []) + ).to.be.revertedWith(ERRORS.PUBLICATION_DOES_NOT_EXIST); + }); + + it('User should fail to process collect over existent yet unavailable auction', async function () { + const futureTimestamp = (await getTimestamp()) + ONE_DAY_IN_SECONDS; + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ + availableSinceTimestamp: futureTimestamp, + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, pubId, []) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to process collect over existent available but unstarted auction', async function () { + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.ONGOING_AUCTION); + }); + + it('User should fail to process collect over active auction', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.ONGOING_AUCTION); + }); + + it('User should fail to process collect if he is not the auction winner', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + expect(auction.winner).to.be.equals(bidder.address); + expect(bidder.address).to.not.be.equal(anotherUser.address); + await expect( + lensHub.connect(anotherUser).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process collect if collects through a publication that makes lens hub pass a wrong referrer profile ID', async function () { + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const mirrorPubId = FIRST_PUB_ID; + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, mirrorPubId, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + expect(auction.winner).to.be.equals(bidder.address); + const referrerProfileIdOfWinner = await auctionCollectModule.getReferrerProfileIdOf( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + auction.winner + ); + expect(referrerProfileIdOfWinner).to.be.equals(referrerProfileId); + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process collect if publication was already collected', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const auction = await auctionCollectModule.getAuctionData(FIRST_PROFILE_ID, FIRST_PUB_ID); + expect(auction.collected).to.be.true; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.be.revertedWith(ERRORS.COLLECT_ALREADY_PROCESSED); + }); + + it('User should fail to process collect if is only for followers and and he is not following the publication owner', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect(lensHub.connect(bidder).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await simulateAuctionEnd({ + pubId: pubId, + }); + const followNftAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNft = await FollowNFT__factory.connect(followNftAddress, bidder); + await expect( + followNft.transferFrom(bidder.address, anotherUser.address, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await expect( + lensHub + .connect(bidder) + .collect(FIRST_PROFILE_ID, pubId, abiCoder.encode(['uint256'], [FIRST_FOLLOW_NFT_ID])) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to process collect if is only for followers and and he followed publication owner after auction started', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect(lensHub.connect(bidder).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await simulateAuctionEnd({ + pubId: pubId, + }); + const followNftAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNft = await FollowNFT__factory.connect(followNftAddress, bidder); + await expect(followNft.burn(FIRST_FOLLOW_NFT_ID)).to.not.be.reverted; + await expect(lensHub.connect(bidder).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted; + const newFollowNftId = FIRST_FOLLOW_NFT_ID + 1; + await expect( + lensHub + .connect(bidder) + .collect(FIRST_PROFILE_ID, pubId, abiCoder.encode(['uint256'], [newFollowNftId])) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to process collect if auction was open for everyone and he passed any arbitrary data', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const dataThatShouldNotBePassed = abiCoder.encode(['uint256'], [FIRST_FOLLOW_NFT_ID]); + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, dataThatShouldNotBePassed) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process fees over unexistent publication', async function () { + const unexistentPubId = 69; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, unexistentPubId) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to process fees over publication that uses another collect module', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, pubId) + ).to.be.revertedWith(ERRORS.UNAVAILABLE_AUCTION); + }); + + it('User should fail to process fees over unstarted auction', async function () { + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.be.revertedWith(ERRORS.ONGOING_AUCTION); + }); + + it('User should fail to process fees over active auction', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.be.revertedWith(ERRORS.ONGOING_AUCTION); + }); + + it('User should fail to process fees over auction that already processed fees through process collect call', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const auctionBeforeCollect = await auctionCollectModule.getAuctionData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ); + expect(auctionBeforeCollect.collected).to.be.false; + expect(auctionBeforeCollect.feeProcessed).to.be.false; + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const auctionAfterCollect = await auctionCollectModule.getAuctionData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ); + expect(auctionAfterCollect.collected).to.be.true; + expect(auctionAfterCollect.feeProcessed).to.be.true; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.be.revertedWith(ERRORS.FEE_ALREADY_PROCESSED); + }); + + it('User should fail to process fees over auction that already processed fee through process fees call', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const auctionBeforeCollectFee = await auctionCollectModule.getAuctionData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ); + expect(auctionBeforeCollectFee.collected).to.be.false; + expect(auctionBeforeCollectFee.feeProcessed).to.be.false; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.not.be.reverted; + const auctionAfterCollectFee = await auctionCollectModule.getAuctionData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ); + expect(auctionAfterCollectFee.collected).to.be.false; + expect(auctionAfterCollectFee.feeProcessed).to.be.true; + await expect( + auctionCollectModule.connect(bidder).processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.be.revertedWith(ERRORS.FEE_ALREADY_PROCESSED); + }); + }); + + context('Scenarios', function () { + it('User should win and collect an only followers auction borrowing different follow NFTs through the entire process', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ onlyFollowers: true }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + // Two different users follow publisher profile before the auction starts + await expect( + lensHub.connect(anotherUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + await expect( + lensHub.connect(thirdUser).follow([FIRST_PROFILE_ID], [[]]) + ).to.not.be.reverted; + const secondFollowNftId = FIRST_FOLLOW_NFT_ID + 1; + const followNftAddress = await lensHub.getFollowNFT(FIRST_PROFILE_ID); + const followNft = await FollowNFT__factory.connect(followNftAddress, bidder); + // We verify the users has a follow NFT now but the bidder does not + expect((await followNft.balanceOf(bidder.address)).isZero()).to.be.true; + expect((await followNft.balanceOf(anotherUser.address)).isZero()).to.be.false; + expect((await followNft.balanceOf(thirdUser.address)).isZero()).to.be.false; + // Bidder takes follow NFT from anotherUser, places a bid and return it back + await expect( + followNft + .connect(anotherUser) + .transferFrom(anotherUser.address, bidder.address, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, pubId, DEFAULT_AMOUNT, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + await expect( + followNft + .connect(bidder) + .transferFrom(bidder.address, anotherUser.address, FIRST_FOLLOW_NFT_ID) + ).to.not.be.reverted; + // Auction ends, bidder becomes the winner + await simulateAuctionEnd({ + pubId: pubId, + }); + // Bidder takes follow NFT from thirdUser to be able to collect + await expect( + followNft + .connect(thirdUser) + .transferFrom(thirdUser.address, bidder.address, secondFollowNftId) + ).to.not.be.reverted; + await expect( + lensHub + .connect(bidder) + .collect(FIRST_PROFILE_ID, pubId, abiCoder.encode(['uint256'], [secondFollowNftId])) + ).to.not.be.reverted; + }); + + it('Anoyone should succeed to trigger collect fees processing after auction finishes before the winner collects', async function () { + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + const treasuryBalanceBeforeFees = await currency.balanceOf(treasury.address); + const recipientBalanceBeforeFees = await currency.balanceOf(feeRecipient.address); + const tx = auctionCollectModule + .connect(anotherUser) + .processCollectFee(FIRST_PROFILE_ID, FIRST_PUB_ID); + const txReceipt = await waitForTx(tx); + matchEvent( + txReceipt, + 'FeeProcessed', + [FIRST_PROFILE_ID, FIRST_PUB_ID, await getTimestamp()], + auctionCollectModule + ); + const treasuryBalanceAfterFees = await currency.balanceOf(treasury.address); + const recipientBalanceAfterFees = await currency.balanceOf(feeRecipient.address); + await expect( + lensHub.connect(bidder).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedTreausyFee = DEFAULT_AMOUNT.mul(TREASURY_FEE_BPS).div(BPS_MAX); + const expectedRecipientFee = DEFAULT_AMOUNT.sub(expectedTreausyFee); + expect(treasuryBalanceBeforeFees.isZero()).to.be.true; + expect(recipientBalanceBeforeFees.isZero()).to.be.true; + expect(treasuryBalanceAfterFees).to.be.equals(expectedTreausyFee); + expect(recipientBalanceAfterFees).to.be.equals(expectedRecipientFee); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceAfterFees); + expect(recipientBalanceAfterCollect).to.be.equals(recipientBalanceAfterFees); + }); + + it('Owner of referrer profile should receive a cut of the collect fees', async function () { + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Creates referrer profile who mirrors publication + await lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Bidder places a bid through mirrored publication + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + // Auction finishes + await simulateAuctionEnd({}); + // Collects through same mirrored publication as it is required + await expect( + lensHub.connect(bidder).collect(referrerProfileId, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedTreasuryFee = DEFAULT_AMOUNT.mul(TREASURY_FEE_BPS).div(BPS_MAX); + const expectedScaledAmount = DEFAULT_AMOUNT.sub(expectedTreasuryFee); + const expectedReferralFee = expectedScaledAmount.mul(REFERRAL_FEE_BPS).div(BPS_MAX); + const expectedRecipientFee = expectedScaledAmount.sub(expectedReferralFee); + expect(treasuryBalanceAfterCollect).to.be.equals( + treasuryBalanceBeforeCollect.add(expectedTreasuryFee) + ); + expect(referrerBalanceAfterCollect).to.be.equals( + referrerBalanceBeforeCollect.add(expectedReferralFee) + ); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedRecipientFee) + ); + }); + + it('Owner of referrer profile should not receive collect fees if referrer fee was set to zero', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ referralFee: 0 }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Creates referrer profile who mirrors publication + await lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: pubId, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Bidder places a bid through mirrored publication + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + // Auction finishes + await simulateAuctionEnd({ pubId: pubId }); + // Collects through same mirrored publication as it is required + await expect( + lensHub.connect(bidder).collect(referrerProfileId, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedTreasuryFee = DEFAULT_AMOUNT.mul(TREASURY_FEE_BPS).div(BPS_MAX); + const expectedScaledAmount = DEFAULT_AMOUNT.sub(expectedTreasuryFee); + expect(treasuryBalanceAfterCollect).to.be.equals( + treasuryBalanceBeforeCollect.add(expectedTreasuryFee) + ); + expect(referrerBalanceAfterCollect).to.be.equals(referrerBalanceBeforeCollect); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedScaledAmount) + ); + }); + + it('Fee recipient should receive all collect fees when publication is collected through original publication and treasury fee was set to zero', async function () { + await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + await expect( + auctionCollectModule + .connect(bidder) + .bid(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + await simulateAuctionEnd({}); + await expect( + lensHub.connect(bidder).collect(FIRST_PUB_ID, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceBeforeCollect); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(DEFAULT_AMOUNT) + ); + }); + + it('Fee recipient and referrer profile owners should share the entire fees between them if treasury feet was set to zero', async function () { + await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Creates referrer profile who mirrors publication + await lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Bidder places a bid through mirrored publication + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + // Auction finishes + await simulateAuctionEnd({}); + // Collects through same mirrored publication as it is required + await expect( + lensHub.connect(bidder).collect(referrerProfileId, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedReferralFee = DEFAULT_AMOUNT.mul(REFERRAL_FEE_BPS).div(BPS_MAX); + const expectedRecipientFee = DEFAULT_AMOUNT.sub(expectedReferralFee); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceBeforeCollect); + expect(referrerBalanceAfterCollect).to.be.equals( + referrerBalanceBeforeCollect.add(expectedReferralFee) + ); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedRecipientFee) + ); + expect( + recipientBalanceAfterCollect + .sub(recipientBalanceBeforeCollect) + .add(referrerBalanceAfterCollect) + .sub(referrerBalanceBeforeCollect) + ).to.be.equals(DEFAULT_AMOUNT); + }); + + it('Publication owner should get the entire collect fees if referrer and treasury fees were set to zero', async function () { + await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted; + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: auctionCollectModule.address, + collectModuleInitData: await getAuctionCollectModuleInitData({ referralFee: 0 }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + const pubId = FIRST_PUB_ID + 1; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Creates referrer profile who mirrors publication + await lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }); + const referrerProfileId = FIRST_PROFILE_ID + 1; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: referrerProfileId, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: pubId, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Bidder places a bid through mirrored publication + await expect( + auctionCollectModule + .connect(bidder) + .bid(referrerProfileId, FIRST_PUB_ID, DEFAULT_AMOUNT, 0) + ).to.not.be.reverted; + // Auction finishes + await simulateAuctionEnd({ pubId: pubId }); + // Collects through same mirrored publication as it is required + await expect( + lensHub.connect(bidder).collect(referrerProfileId, FIRST_PUB_ID, []) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceBeforeCollect); + expect(referrerBalanceAfterCollect).to.be.equals(referrerBalanceBeforeCollect); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(DEFAULT_AMOUNT) + ); + }); + }); + }); +}); diff --git a/lens-protocol/modules/test/modules/collect/partial-carbon-retirement-collect-module.ts b/lens-protocol/modules/test/modules/collect/partial-carbon-retirement-collect-module.ts new file mode 100644 index 0000000..e1740fa --- /dev/null +++ b/lens-protocol/modules/test/modules/collect/partial-carbon-retirement-collect-module.ts @@ -0,0 +1,77 @@ + +/** + * This file contains the relevant test cases for the related collect module + * + * Implementation is not needed until LensV2 is published, + * because the test environment is different there + * + * Description follows the function names in + * https://github.com/lens-protocol/core/blob/v2/test/modules/act/collect/BaseFeeCollectModule.t.sol + * + * + * + * ------------------------- + * Initialization test cases + * ------------------------- + * + * From BaseFeeCollectModule (see link above): + * ------------------------------------------ + * + * testCannotInitializeWithNonWhitelistedCurrency + * testCannotInitializeWithReferralFeeGreaterThanMaxBPS + * testCannotInitializeWithPastNonzeroTimestamp + * testCannotInitializeIfCalledFromNonActionModuleAddress + * testCannotInitializeWithWrongInitDataFormat + * + * testInitializeWithCorrectInitData + * + * + * Specific for PartialCarbonRetirementCollectModule: + * --------------------------------------------------- + * + * testCannotInitializeWithNonWhitelistedPoolToken + * testCannotInitializeIfNoSwapPathFromCurrencyToPoolTokenExists + * testCannotInitializeWithRetirementSplitGreaterThanMaxBPS + * + * + * ------------------------- + * Collection test cases + * ------------------------- + * + * From BaseFeeCollectModule (see link above): + * ------------------------------------------ + * + * testCannotProcessCollect_IfCalledFrom_NonActionModuleAddress + * testCannotProcessCollect_PassingWrongAmountInData + * testCannotProcessCollect_PassingWrongCurrencyInData + * testCannotCollectIfNotAFollower + * testCannotProcessCollect_AfterEndTimestamp + * testCannotCollectMoreThanLimit + * + * testCanCollectIfAllConditionsAreMet + * testCurrentCollectsIncreaseProperlyWhenCollecting + * + * Specific for PartialCarbonRetirementCollectModule: + * --------------------------------------------------- + * + * testCannotProcessCollect_PassingWrongPoolTokenInData + * testCannotProcessCollect_PassingWrongRetirementSplitInData + * + * testCanCollectWithoutRetirementIfNoSwapPathFromCurrencyToPoolTokenExists + * testCanCollectWithRecipientAmountIsFullAmountIfNoSwapPathFromCurrencyToPoolTokenExists + * + * + * ------------------------- + * Fee distribution + * ------------------------- + * + * From BaseFeeCollectModule (see link above): + * ------------------------------------------ + * + * testVerifyFeesSplit + * + * + * + * + * +*/ diff --git a/lens-protocol/modules/test/modules/collect/updatable-ownable-fee-collect-module.spec.ts b/lens-protocol/modules/test/modules/collect/updatable-ownable-fee-collect-module.spec.ts new file mode 100644 index 0000000..c53aed7 --- /dev/null +++ b/lens-protocol/modules/test/modules/collect/updatable-ownable-fee-collect-module.spec.ts @@ -0,0 +1,1446 @@ +import { BigNumber, BigNumberish } from '@ethersproject/bignumber'; +import { parseEther } from '@ethersproject/units'; +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { UpdatableOwnableFeeCollectModule__factory } from '../../../typechain'; +import { ERRORS } from '../../helpers/errors'; +import { + abiCoder, + updatableOwnableFeeCollectModule, + BPS_MAX, + chainId, + currency, + feeRecipient, + FIRST_PROFILE_ID, + FIRST_PUB_ID, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_PROFILE_HANDLE, + MOCK_URI, + moduleGlobals, + anotherUser, + REFERRAL_FEE_BPS, + user, + deployer, + treasury, + TREASURY_FEE_BPS, + governance, + DEFAULT_AMOUNT, +} from './../../__setup.spec'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { publisher } from '../../__setup.spec'; +import { getTimestamp, matchEvent, setNextBlockTimestamp, waitForTx } from '../../helpers/utils'; +import { Domain } from '../../helpers/signatures/utils'; +import { PubType } from '../../helpers/constants'; +import { signUpdateModuleParametersWithSigMessage } from '../../helpers/signatures/modules/collect/updatable-ownable-fee-collect-module'; +import { base64 } from 'ethers/lib/utils'; + +export let UPDATE_MODULE_PARAMETERS_WITH_SIG_DOMAIN: Domain; + +makeSuiteCleanRoom('UpdatableOwnableFeeCollectModule', function () { + const FIRST_TOKEN_ID = ethers.constants.One; + let DEFAULT_COLLECT_DATA; + + interface UpdatableOwnableFeeCollectModuleInitData { + amount?: BigNumber; + feeCurrency?: string; + recipient?: string; + referralFee?: number; + followerOnly?: boolean; + } + + async function getUpdatableOwnableFeeCollectModuleInitData({ + amount = DEFAULT_AMOUNT, + feeCurrency = currency.address, + recipient = feeRecipient.address, + referralFee = REFERRAL_FEE_BPS, + followerOnly = false, + }: UpdatableOwnableFeeCollectModuleInitData): Promise { + return abiCoder.encode( + ['uint256', 'address', 'address', 'uint16', 'bool'], + [amount, feeCurrency, recipient, referralFee, followerOnly] + ); + } + + interface MintAndApproveCurrency { + owner?: SignerWithAddress; + spender?: string; + amountToMint?: BigNumberish; + amountToApprove?: BigNumberish; + } + + async function mintAndApproveCurrency({ + owner = user, + spender = updatableOwnableFeeCollectModule.address, + amountToMint = parseEther('100000'), + amountToApprove = ethers.constants.MaxUint256, + }: MintAndApproveCurrency) { + await currency.connect(owner).mint(owner.address, amountToMint); + await currency.connect(owner).approve(spender, amountToApprove); + } + + beforeEach(async function () { + UPDATE_MODULE_PARAMETERS_WITH_SIG_DOMAIN = { + name: 'UpdatableOwnableFeeCollectModule', + version: '1', + chainId: chainId, + verifyingContract: updatableOwnableFeeCollectModule.address, + }; + await expect( + lensHub.createProfile({ + to: publisher.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('UpdatableOwnableFeeCollectModule', function () { + context('Publication creation', function () { + context('Negatives', function () { + it('User should fail to post using unwhitelisted currency', async function () { + const unwhitelistedCurrency = ethers.constants.AddressZero; + expect(await moduleGlobals.isCurrencyWhitelisted(unwhitelistedCurrency)).to.be.false; + const collectModuleInitData = await getUpdatableOwnableFeeCollectModuleInitData({ + feeCurrency: unwhitelistedCurrency, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('User should fail to post using referral fee greater than max BPS', async function () { + const referralFee = BPS_MAX + 1; + expect(referralFee).to.be.greaterThan(BPS_MAX); + const collectModuleInitData = await getUpdatableOwnableFeeCollectModuleInitData({ + referralFee: referralFee, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: collectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + + it('User should fail to post passing data with wrong format', async function () { + const wrongFormattedCollectModuleInitData = abiCoder.encode( + ['uint256', 'address', 'bool'], + [DEFAULT_AMOUNT, currency.address, false] + ); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: wrongFormattedCollectModuleInitData, + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.reverted; + }); + + it('Module initialization should fail if the call is not done by the hub', async function () { + expect(publisher.address).to.not.equal(lensHub.address); + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .initializePublicationCollectModule( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + await getUpdatableOwnableFeeCollectModuleInitData({}) + ) + ).to.be.revertedWith(ERRORS.NOT_HUB); + }); + }); + + context('Scenarios', function () { + it('User should be able to create a publication that burns tokens by setting the recipient as the zero address', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: await getUpdatableOwnableFeeCollectModuleInitData({ + recipient: ethers.constants.AddressZero, + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT, + currency.address, + ethers.constants.AddressZero, + REFERRAL_FEE_BPS, + false, + ]); + }); + + it('User should be able to create a publication with zero fees', async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: await getUpdatableOwnableFeeCollectModuleInitData({ + amount: ethers.constants.Zero, + }), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + ethers.constants.Zero, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + ]); + }); + + it('Ownership NFT should be minted to the publication author after a publishing succeeded', async function () { + expect(await updatableOwnableFeeCollectModule.totalSupply()).to.be.equals(0); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: await getUpdatableOwnableFeeCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + ]); + // Checks now one NFT has been issued and its owner is the publisher + expect(await updatableOwnableFeeCollectModule.totalSupply()).to.be.equals( + ethers.constants.One + ); + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + publisher.address + ); + }); + }); + }); + + context('Publication reverse resolution by token ID', function () { + context('Negatives', function () { + it('Fails to retrieve publication if token ID does not exist', async function () { + expect(await updatableOwnableFeeCollectModule.totalSupply()).to.be.equals( + ethers.constants.Zero + ); + await expect( + updatableOwnableFeeCollectModule.getPublicationByTokenId(FIRST_TOKEN_ID) + ).to.revertedWith(ERRORS.TOKEN_DOES_NOT_EXIST); + }); + }); + + context('Scenarios', function () { + it('Returns the correct information after publication has been created', async function () { + // Creates publication + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: await getUpdatableOwnableFeeCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Checks the reverse publication resolution by token ID gets the correct information + expect( + await updatableOwnableFeeCollectModule.getPublicationByTokenId(FIRST_TOKEN_ID) + ).to.eqls([ + ethers.constants.Zero, + ethers.constants.Zero, + MOCK_URI, + ethers.constants.AddressZero, + updatableOwnableFeeCollectModule.address, + ethers.constants.AddressZero, + ]); + }); + }); + }); + + context('Ownership NFT token URI', function () { + context('Negatives', function () { + it('Fails to retrieve the token URI if token ID does not exist', async function () { + expect(await updatableOwnableFeeCollectModule.totalSupply()).to.be.equals( + ethers.constants.Zero + ); + await expect(updatableOwnableFeeCollectModule.tokenURI(FIRST_TOKEN_ID)).to.revertedWith( + ERRORS.TOKEN_DOES_NOT_EXIST + ); + }); + }); + + context('Scenarios', function () { + it('Returns the correct token URI after publication has been created', async function () { + // Creates publication + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: await getUpdatableOwnableFeeCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Checks the reverse publication resolution by token ID gets the correct information + const tokenURI = await updatableOwnableFeeCollectModule.tokenURI(FIRST_TOKEN_ID); + const jsonMetadataBase64String = tokenURI.split('data:application/json;base64,')[1]; + const jsonMetadataBytes = ethers.utils.base64.decode(jsonMetadataBase64String); + const jsonMetadataString = ethers.utils.toUtf8String(jsonMetadataBytes); + const jsonMetadata = JSON.parse(jsonMetadataString); + expect(jsonMetadata).to.eql({ + name: 'Ownership of Lens Publication #1-1', + description: + 'Owning this NFT allows the owner to change the collect parameters of the #1-1 publication.', + image: 'ipfs://bafkreifclgvhtotpoquwoo7enjof6xfqjbthukddkxagtykjfnc3kh6khm', + }); + }); + }); + }); + + context('Update module params', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: await getUpdatableOwnableFeeCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('User should fail to update module parameters if he is not owning the corresponding ownership NFT', async function () { + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + publisher.address + ); + expect(anotherUser.address).to.not.be.equals(publisher.address); + await expect( + updatableOwnableFeeCollectModule + .connect(anotherUser) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + true + ) + ).to.be.revertedWith(ERRORS.ONLY_OWNER); + }); + + it('User should fail to update module parameters if he is not owning the corresponding ownership NFT after being trasnferred', async function () { + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + publisher.address + ); + expect(anotherUser.address).to.not.be.equals(publisher.address); + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .transferFrom(publisher.address, anotherUser.address, FIRST_TOKEN_ID) + ).to.not.be.reverted; + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + anotherUser.address + ); + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + true + ) + ).to.be.revertedWith(ERRORS.ONLY_OWNER); + }); + + it('User should fail to update module parameters if he is setting an unwhitelisted currency', async function () { + const unwhitelistedCurrency = ethers.constants.AddressZero; + expect(await moduleGlobals.isCurrencyWhitelisted(unwhitelistedCurrency)).to.be.false; + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + unwhitelistedCurrency, + feeRecipient.address, + REFERRAL_FEE_BPS, + true + ) + ).to.be.revertedWith(ERRORS.INVALID_PARAMETERS); + }); + + it('User should fail to update module parameters if he is setting a referral fee greater than max BPS', async function () { + const referralFee = BPS_MAX + 1; + expect(referralFee).to.be.greaterThan(BPS_MAX); + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + referralFee, + true + ) + ).to.be.revertedWith(ERRORS.INVALID_PARAMETERS); + }); + + it('User should fail to update module parameters if publication does not exists', async function () { + const unexistentPubId = 69; + expect(await lensHub.getPubType(FIRST_PROFILE_ID, unexistentPubId)).to.equals( + PubType.Nonexistent + ); + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + unexistentPubId, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + true + ) + ).to.be.revertedWith(ERRORS.ERC721_QUERY_FOR_NONEXISTENT_TOKEN); + }); + }); + + context('Scenarios', function () { + it('User should be able to update parameters if owns the ownership NFT and that should emit the expected event', async function () { + // Verifies the owner before and after the ownership NFT transfer + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + publisher.address + ); + // Verifies the parameters before being changed + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + ]); + // Updates the parameters + const tx = updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + ethers.constants.AddressZero, + REFERRAL_FEE_BPS, + true + ); + const txReceipt = await waitForTx(tx); + // Verifies the expected event has been emited + matchEvent( + txReceipt, + 'ModuleParametersUpdated', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + ethers.constants.AddressZero, + REFERRAL_FEE_BPS, + true, + ], + updatableOwnableFeeCollectModule + ); + // Verifies the parameters has been changed + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + ethers.constants.AddressZero, + REFERRAL_FEE_BPS, + true, + ]); + }); + + it('User should be able to update parameters if owns the ownership NFT after it being transferred', async function () { + // Verifies the owner before and after the ownership NFT transfer + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + publisher.address + ); + expect(anotherUser.address).to.not.be.equals(publisher.address); + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .transferFrom(publisher.address, anotherUser.address, FIRST_TOKEN_ID) + ).to.not.be.reverted; + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + anotherUser.address + ); + // Verifies the parameters before being changed + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + ]); + // The new owner updates the parameters + await expect( + updatableOwnableFeeCollectModule + .connect(anotherUser) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + ethers.constants.AddressZero, + REFERRAL_FEE_BPS, + true + ) + ).to.not.be.reverted; + // Verifies the parameters has been changed + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + ethers.constants.AddressZero, + REFERRAL_FEE_BPS, + true, + ]); + }); + }); + }); + + context('Update module params with sig', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: await getUpdatableOwnableFeeCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('User should fail to update module params with sig if recovered signer does not match the expected one', async function () { + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: anotherUser, + }); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message deadline was exceeded', async function () { + const expiredDeadline = ethers.constants.One; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + deadline: expiredDeadline, + }); + expect(expiredDeadline.lt(await getTimestamp())).to.be.true; + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('User should fail to update module params with sig if signed message had wrong nonce', async function () { + const currentNonce = await updatableOwnableFeeCollectModule.sigNonces(publisher.address); + const invalidNonce = await currentNonce.add(5); + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + nonce: invalidNonce, + }); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message domain had wrong version', async function () { + const invalidVersion = '0'; + const invalidDomain: Domain = { + name: 'UpdatableOwnableFeeCollectModule', + version: invalidVersion, + chainId: chainId, + verifyingContract: updatableOwnableFeeCollectModule.address, + }; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + domain: invalidDomain, + }); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message domain had wrong chain ID', async function () { + const invalidChainId = 69; + expect(chainId).to.not.equals(invalidChainId); + const invalidDomain: Domain = { + name: 'UpdatableOwnableFeeCollectModule', + version: '1', + chainId: invalidChainId, + verifyingContract: updatableOwnableFeeCollectModule.address, + }; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + domain: invalidDomain, + }); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message domain had wrong verifying contract', async function () { + const invalidVerifyingContract = ( + await new UpdatableOwnableFeeCollectModule__factory(deployer).deploy( + lensHub.address, + moduleGlobals.address + ) + ).address; + const invalidDomain: Domain = { + name: 'UpdatableOwnableFeeCollectModule', + version: '1', + chainId: chainId, + verifyingContract: invalidVerifyingContract, + }; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + domain: invalidDomain, + }); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message domain had wrong name', async function () { + const invalidName = 'Updatable Ownable Fee Collect Module'; + const invalidDomain: Domain = { + name: invalidName, + version: '1', + chainId: chainId, + verifyingContract: updatableOwnableFeeCollectModule.address, + }; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + domain: invalidDomain, + }); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module parameters if he is not owning the corresponding ownership NFT', async function () { + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + publisher.address + ); + expect(anotherUser.address).to.not.be.equals(publisher.address); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + anotherUser.address, + await signUpdateModuleParametersWithSigMessage({ signer: anotherUser }) + ) + ).to.be.revertedWith(ERRORS.ONLY_OWNER); + }); + + it('User should fail to update module parameters if he is not owning the corresponding ownership NFT after being trasnferred', async function () { + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + publisher.address + ); + expect(anotherUser.address).to.not.be.equals(publisher.address); + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .transferFrom(publisher.address, anotherUser.address, FIRST_TOKEN_ID) + ).to.not.be.reverted; + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + anotherUser.address + ); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + await signUpdateModuleParametersWithSigMessage({ signer: publisher }) + ) + ).to.be.revertedWith(ERRORS.ONLY_OWNER); + }); + + it('User should fail to update module parameters if he is setting an unwhitelisted currency', async function () { + const unwhitelistedCurrency = ethers.constants.AddressZero; + expect(await moduleGlobals.isCurrencyWhitelisted(unwhitelistedCurrency)).to.be.false; + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + unwhitelistedCurrency, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + feeCurrency: unwhitelistedCurrency, + }) + ) + ).to.be.revertedWith(ERRORS.INVALID_PARAMETERS); + }); + + it('User should fail to update module parameters if he is setting a referral fee greater than max BPS', async function () { + const referralFee = BPS_MAX + 1; + expect(referralFee).to.be.greaterThan(BPS_MAX); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + referralFee, + false, + publisher.address, + await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + referralFee: referralFee, + }) + ) + ).to.be.revertedWith(ERRORS.INVALID_PARAMETERS); + }); + + it('User should fail to update module parameters if publication does not exists', async function () { + const unexistentPubId = 69; + expect(await lensHub.getPubType(FIRST_PROFILE_ID, unexistentPubId)).to.equals( + PubType.Nonexistent + ); + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + unexistentPubId, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + publisher.address, + await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + pubId: unexistentPubId, + }) + ) + ).to.be.revertedWith(ERRORS.ERC721_QUERY_FOR_NONEXISTENT_TOKEN); + }); + }); + + context('Scenarios', function () { + it('User should be able to update parameters through sig if owns the ownership NFT and that should emit the expected event', async function () { + // Verifies the owner before and after the ownership NFT transfer + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + publisher.address + ); + // Verifies the parameters before being changed + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + ]); + // Updates the parameters + const tx = updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + true, + publisher.address, + await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + amount: DEFAULT_AMOUNT.add(1), + followerOnly: true, + }) + ); + const txReceipt = await waitForTx(tx); + // Verifies the expected event has been emited + matchEvent( + txReceipt, + 'ModuleParametersUpdated', + [ + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + true, + ], + updatableOwnableFeeCollectModule + ); + // Verifies the parameters has been changed + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + true, + ]); + }); + + it('User should be able to update parameters through sig if owns the ownership NFT after it being transferred', async function () { + // Verifies the owner before and after the ownership NFT transfer + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + publisher.address + ); + expect(anotherUser.address).to.not.be.equals(publisher.address); + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .transferFrom(publisher.address, anotherUser.address, FIRST_TOKEN_ID) + ).to.not.be.reverted; + expect(await updatableOwnableFeeCollectModule.ownerOf(FIRST_TOKEN_ID)).to.be.equals( + anotherUser.address + ); + // Verifies the parameters before being changed + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false, + ]); + // The new owner updates the parameters + await expect( + updatableOwnableFeeCollectModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + true, + anotherUser.address, + await signUpdateModuleParametersWithSigMessage({ + signer: anotherUser, + amount: DEFAULT_AMOUNT.add(1), + followerOnly: true, + }) + ) + ).to.not.be.reverted; + // Verifies the parameters has been changed + expect( + await updatableOwnableFeeCollectModule.getPublicationData( + FIRST_PROFILE_ID, + FIRST_PUB_ID + ) + ).to.eqls([ + FIRST_TOKEN_ID, + DEFAULT_AMOUNT.add(1), + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + true, + ]); + }); + }); + }); + + context('Collect fees', function () { + const REFERRER_PROFILE_ID = FIRST_PROFILE_ID + 1; + + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: updatableOwnableFeeCollectModule.address, + collectModuleInitData: await getUpdatableOwnableFeeCollectModuleInitData({}), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + DEFAULT_COLLECT_DATA = abiCoder.encode( + ['address', 'uint256'], + [currency.address, DEFAULT_AMOUNT] + ); + }); + + context('Negatives', function () { + it('Process collect call should fail if caller is not the hub', async function () { + await expect( + updatableOwnableFeeCollectModule + .connect(user) + .processCollect(0, user.address, FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.be.revertedWith(ERRORS.NOT_HUB); + }); + + it('User should fail to process collect over unexistent publication', async function () { + const unexistentPubId = 69; + expect(await lensHub.getPubType(FIRST_PROFILE_ID, unexistentPubId)).to.equals( + PubType.Nonexistent + ); + await expect( + lensHub.connect(user).collect(FIRST_PROFILE_ID, unexistentPubId, DEFAULT_COLLECT_DATA) + ).to.be.revertedWith(ERRORS.PUBLICATION_DOES_NOT_EXIST); + }); + + it('User should fail to process collect if is only for followers and and he is not following the publication owner', async function () { + // Updates the parameters to set the publication as collectable only by followers + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + true + ) + ).to.not.be.reverted; + // Executes the collect call + await expect( + lensHub.connect(user).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to process collect if the expected amount mismatch', async function () { + // The owner updates the parameters to raise the collect price + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT.mul(2), + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false + ) + ).to.not.be.reverted; + // Executes the collect call but passing through the old price as expected + await expect( + lensHub.connect(user).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process collect if the expected currency mismatch', async function () { + // Executes the collect call but passing through a different currency as expected + const dataWithWrongCurrency = abiCoder.encode( + ['address', 'uint256'], + [ethers.constants.AddressZero, DEFAULT_AMOUNT] + ); + await expect( + lensHub.connect(user).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, dataWithWrongCurrency) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process collect if has not approved the currency to be spent by the module', async function () { + await mintAndApproveCurrency({ amountToApprove: 0 }); + await expect( + lensHub.connect(user).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.be.revertedWith(ERRORS.ERC20_INSUFFICIENT_ALLOWANCE); + }); + + it('User should fail to process collect if has approved the currency to be spent by the module but does not have enough balance', async function () { + await mintAndApproveCurrency({ amountToMint: 0 }); + await expect( + lensHub.connect(user).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.be.revertedWith(ERRORS.ERC20_TRANSFER_EXCEEDS_BALANCE); + }); + + it('User should fail to process collect if the expected amount mismatch when collecting through a mirror', async function () { + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: REFERRER_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // The owner updates the parameters to raise the collect price + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT.mul(2), + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false + ) + ).to.not.be.reverted; + // Executes the collect call but passing through the old price as expected + await expect( + lensHub.connect(user).collect(REFERRER_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process collect if the expected currency mismatch when collecting through a mirror', async function () { + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: REFERRER_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + // Executes the collect call but passing through a different currency as expected + const dataWithWrongCurrency = abiCoder.encode( + ['address', 'uint256'], + [ethers.constants.AddressZero, DEFAULT_AMOUNT] + ); + await expect( + lensHub.connect(user).collect(REFERRER_PROFILE_ID, FIRST_PUB_ID, dataWithWrongCurrency) + ).to.be.revertedWith(ERRORS.MODULE_DATA_MISMATCH); + }); + + it('User should fail to process collect if has not approved the currency to be spent by the module when collecting through a mirror', async function () { + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: REFERRER_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({ amountToApprove: 0 }); + await expect( + lensHub.connect(user).collect(REFERRER_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.be.revertedWith(ERRORS.ERC20_INSUFFICIENT_ALLOWANCE); + }); + + it('User should fail to process collect if has approved the currency to be spent by the module but does not have enough balance when collecting through a mirror', async function () { + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: REFERRER_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({ amountToMint: 0 }); + await expect( + lensHub.connect(user).collect(REFERRER_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.be.revertedWith(ERRORS.ERC20_TRANSFER_EXCEEDS_BALANCE); + }); + }); + + context('Scenarios', function () { + beforeEach(async function () { + // Creates a new profile + await expect( + lensHub.createProfile({ + to: anotherUser.address, + handle: 'referrer.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + // The created profile + await expect( + lensHub.connect(anotherUser).mirror({ + profileId: REFERRER_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + await mintAndApproveCurrency({}); + }); + + it('Owner of referrer profile should not receive collect fees if referrer fee was set to zero', async function () { + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Updates the parameters to remove the referrer fees + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + DEFAULT_AMOUNT, + currency.address, + feeRecipient.address, + ethers.constants.Zero, + false + ) + ).to.not.be.reverted; + // Collects through mirrored publication to set a referrer profile + await expect( + lensHub.connect(user).collect(REFERRER_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedTreasuryFee = DEFAULT_AMOUNT.mul(TREASURY_FEE_BPS).div(BPS_MAX); + const expectedScaledAmount = DEFAULT_AMOUNT.sub(expectedTreasuryFee); + expect(treasuryBalanceAfterCollect).to.be.equals( + treasuryBalanceBeforeCollect.add(expectedTreasuryFee) + ); + expect(referrerBalanceAfterCollect).to.be.equals(referrerBalanceBeforeCollect); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedScaledAmount) + ); + }); + + it('Fee recipient should receive all the fees except for the cut corresponding to the treasury', async function () { + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Collects through original publication to avoid setting a referrer profile + await expect( + lensHub.connect(user).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedTreasuryFee = DEFAULT_AMOUNT.mul(TREASURY_FEE_BPS).div(BPS_MAX); + const expectedScaledAmount = DEFAULT_AMOUNT.sub(expectedTreasuryFee); + expect(treasuryBalanceAfterCollect).to.be.equals( + treasuryBalanceBeforeCollect.add(expectedTreasuryFee) + ); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedScaledAmount) + ); + }); + + it('Recipient, owner of referrer profile and treasury should receive a cut of the collect fees', async function () { + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Collects through mirrored publication to set a referrer profile + await expect( + lensHub.connect(user).collect(REFERRER_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedTreasuryFee = DEFAULT_AMOUNT.mul(TREASURY_FEE_BPS).div(BPS_MAX); + const expectedScaledAmount = DEFAULT_AMOUNT.sub(expectedTreasuryFee); + const expectedReferralFee = expectedScaledAmount.mul(REFERRAL_FEE_BPS).div(BPS_MAX); + const expectedRecipientFee = expectedScaledAmount.sub(expectedReferralFee); + expect(treasuryBalanceAfterCollect).to.be.equals( + treasuryBalanceBeforeCollect.add(expectedTreasuryFee) + ); + expect(referrerBalanceAfterCollect).to.be.equals( + referrerBalanceBeforeCollect.add(expectedReferralFee) + ); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedRecipientFee) + ); + }); + + it('Owner should receive all collect fees when publication is collected through original publication and treasury fee was set to zero', async function () { + // Sets treasury fee to zero + await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Collects through original publication to avoid setting a referrer profile + await expect( + lensHub.connect(user).collect(FIRST_PUB_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceBeforeCollect); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(DEFAULT_AMOUNT) + ); + }); + + it('Fee recipient and referrer profile owner should share the entire fees between them if treasury feet was set to zero', async function () { + // Sets treasury fee to zero + await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted; + const treasuryBalanceBeforeCollect = await currency.balanceOf(treasury.address); + const referrerBalanceBeforeCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Collects through mirrored publication to set a referrer profile + await expect( + lensHub.connect(user).collect(REFERRER_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.not.be.reverted; + const treasuryBalanceAfterCollect = await currency.balanceOf(treasury.address); + const referrerBalanceAfterCollect = await currency.balanceOf(anotherUser.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + const expectedReferralFee = DEFAULT_AMOUNT.mul(REFERRAL_FEE_BPS).div(BPS_MAX); + const expectedRecipientFee = DEFAULT_AMOUNT.sub(expectedReferralFee); + expect(treasuryBalanceAfterCollect).to.be.equals(treasuryBalanceBeforeCollect); + expect(referrerBalanceAfterCollect).to.be.equals( + referrerBalanceBeforeCollect.add(expectedReferralFee) + ); + expect(recipientBalanceAfterCollect).to.be.equals( + recipientBalanceBeforeCollect.add(expectedRecipientFee) + ); + expect( + recipientBalanceAfterCollect + .sub(recipientBalanceBeforeCollect) + .add(referrerBalanceAfterCollect) + .sub(referrerBalanceBeforeCollect) + ).to.be.equals(DEFAULT_AMOUNT); + }); + + it('No fees charged if collect amount was set to zero', async function () { + const collectorBalanceBeforeCollect = await currency.balanceOf(user.address); + const recipientBalanceBeforeCollect = await currency.balanceOf(feeRecipient.address); + // Updates the parameters to set the collect amount to zero + await expect( + updatableOwnableFeeCollectModule + .connect(publisher) + .updateModuleParameters( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + ethers.constants.Zero, + currency.address, + feeRecipient.address, + REFERRAL_FEE_BPS, + false + ) + ).to.not.be.reverted; + // Collects the publication + await expect( + lensHub.connect(user).collect(FIRST_PROFILE_ID, FIRST_PUB_ID, DEFAULT_COLLECT_DATA) + ).to.not.be.reverted; + const collectorBalanceAfterCollect = await currency.balanceOf(user.address); + const recipientBalanceAfterCollect = await currency.balanceOf(feeRecipient.address); + expect(recipientBalanceAfterCollect).to.be.equals(recipientBalanceBeforeCollect); + expect(collectorBalanceAfterCollect).to.be.equals(collectorBalanceBeforeCollect); + }); + }); + }); + }); +}); diff --git a/lens-protocol/modules/test/modules/reference/degrees-of-separation-reference-module.spec.ts b/lens-protocol/modules/test/modules/reference/degrees-of-separation-reference-module.spec.ts new file mode 100644 index 0000000..f8e49ae --- /dev/null +++ b/lens-protocol/modules/test/modules/reference/degrees-of-separation-reference-module.spec.ts @@ -0,0 +1,1068 @@ +import { BigNumber } from '@ethersproject/bignumber'; +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { + DegreesOfSeparationReferenceModule__factory, + FollowNFT__factory, +} from '../../../typechain'; +import { ERRORS } from '../../helpers/errors'; +import { + abiCoder, + chainId, + FIRST_PROFILE_ID, + FIRST_PUB_ID, + lensHub, + makeSuiteCleanRoom, + MOCK_FOLLOW_NFT_URI, + MOCK_URI, + anotherUser, + user, + deployer, + degreesOfSeparationReferenceModule, + thirdUser, + freeCollectModule, + FIRST_FOLLOW_NFT_ID, + profileFollowModule, +} from './../../__setup.spec'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { publisher } from '../../__setup.spec'; +import { getTimestamp, matchEvent, waitForTx } from '../../helpers/utils'; +import { Domain } from '../../helpers/signatures/utils'; +import { signUpdateModuleParametersWithSigMessage } from '../../helpers/signatures/modules/reference/degrees-of-separation-reference-module'; + +export let UPDATE_MODULE_PARAMETERS_WITH_SIG_DOMAIN: Domain; +export let DEFAULT_DEGREES_OF_SEPARATION: number; + +makeSuiteCleanRoom('DegreesOfSeparationReferenceModule', function () { + let ownerOfMirrorAuthor: SignerWithAddress; + let ownerOfCommentAuthor: SignerWithAddress; + let ownerOfFirstDegreeProfile: SignerWithAddress; + let ownerOfSecondDegreeProfile: SignerWithAddress; + const ROOT_AUTHOR_PROFILE: BigNumber = BigNumber.from(1); + const FIRST_DEGREE_PROFILE: BigNumber = BigNumber.from(2); + const SECOND_DEGREE_PROFILE: BigNumber = BigNumber.from(3); + const COMMENTER_PROFILE: BigNumber = BigNumber.from(4); + const MIRRORER_PROFILE: BigNumber = BigNumber.from(4); + + interface DegreesOfSeparationReferenceModuleInitData { + commentsRestricted?: boolean; + mirrorsRestricted?: boolean; + degreesOfSeparation?: number; + } + + async function getDegreesOfSeparationReferenceModuleInitData({ + commentsRestricted = true, + mirrorsRestricted = true, + degreesOfSeparation = DEFAULT_DEGREES_OF_SEPARATION, + }: DegreesOfSeparationReferenceModuleInitData): Promise { + return abiCoder.encode( + ['bool', 'bool', 'uint8'], + [commentsRestricted, mirrorsRestricted, degreesOfSeparation] + ); + } + + beforeEach(async function () { + ownerOfMirrorAuthor = user; + ownerOfCommentAuthor = user; + ownerOfFirstDegreeProfile = anotherUser; + ownerOfSecondDegreeProfile = thirdUser; + UPDATE_MODULE_PARAMETERS_WITH_SIG_DOMAIN = { + name: 'DegreesOfSeparationReferenceModule', + version: '1', + chainId: chainId, + verifyingContract: degreesOfSeparationReferenceModule.address, + }; + DEFAULT_DEGREES_OF_SEPARATION = 3; + await expect( + lensHub.createProfile({ + to: publisher.address, + handle: 'rootpubauthor.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.createProfile({ + to: ownerOfFirstDegreeProfile.address, + handle: 'firstdegree.lens', + imageURI: MOCK_URI, + followModule: profileFollowModule.address, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.createProfile({ + to: ownerOfSecondDegreeProfile.address, + handle: 'seconddegree.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.createProfile({ + to: ownerOfCommentAuthor.address, + handle: 'commentormirrorauthor.lens', + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('DegreesOfSeparationReferenceModule', function () { + context('Publication creation', function () { + context('Negatives', function () { + it('Initialization should fail if it is not called by the hub', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(publisher) + .initializeReferenceModule( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + await getDegreesOfSeparationReferenceModuleInitData({}) + ) + ).to.be.revertedWith(ERRORS.NOT_HUB); + }); + + it('User should fail to post if using wrong degrees of separation as init value', async function () { + const invalidDegreesOfSeparation = 5; + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: degreesOfSeparationReferenceModule.address, + referenceModuleInitData: await getDegreesOfSeparationReferenceModuleInitData({ + degreesOfSeparation: invalidDegreesOfSeparation, + }), + }) + ).to.be.revertedWith(ERRORS.INVALID_DEGREES_OF_SEPARATION); + }); + + it('User should fail to post passing data with wrong format', async function () { + const wrongFormattedReferenceModuleInitData = abiCoder.encode( + ['bool', 'uint8'], + [true, DEFAULT_DEGREES_OF_SEPARATION] + ); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: degreesOfSeparationReferenceModule.address, + referenceModuleInitData: wrongFormattedReferenceModuleInitData, + }) + ).to.be.reverted; + }); + }); + + context('Scenarios', function () { + it('User should be able to create a publication when passing a valid data with valid degrees of separation number', async function () { + const degreesOfSeparation = 4; + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: degreesOfSeparationReferenceModule.address, + referenceModuleInitData: await getDegreesOfSeparationReferenceModuleInitData({ + degreesOfSeparation: degreesOfSeparation, + }), + }) + ).to.not.be.reverted; + expect( + await degreesOfSeparationReferenceModule.getModuleConfig(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.eqls([true, true, true, degreesOfSeparation]); + }); + + it('User should be able to create a publication even using zero as degrees of separation', async function () { + const degreesOfSeparation = 0; + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: degreesOfSeparationReferenceModule.address, + referenceModuleInitData: await getDegreesOfSeparationReferenceModuleInitData({ + degreesOfSeparation: degreesOfSeparation, + }), + }) + ).to.not.be.reverted; + expect( + await degreesOfSeparationReferenceModule.getModuleConfig(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.eqls([true, true, true, degreesOfSeparation]); + }); + }); + }); + + context('Update module parameters', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: ROOT_AUTHOR_PROFILE, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: degreesOfSeparationReferenceModule.address, + referenceModuleInitData: await getDegreesOfSeparationReferenceModuleInitData({}), + }) + ).not.be.reverted; + }); + + context('Negatives', function () { + it('User should fail to update module parameters if he does not own the profile authoring the publication', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(anotherUser) + .updateModuleParameters( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION + ) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER); + }); + + it('User should fail to update module parameters if the publication is not using the degrees of separation reference module', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID + 1, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION + ) + ).to.be.revertedWith(ERRORS.PUBLICATION_NOT_SET_UP); + }); + + it('User should fail to update module parameters if the passed degrees of separation exceeds the maximum allowed one', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters(ROOT_AUTHOR_PROFILE, FIRST_PUB_ID, true, true, 5) + ).to.be.revertedWith(ERRORS.INVALID_DEGREES_OF_SEPARATION); + }); + }); + + context('Scenarios', function () { + it('User should be able to update module parameters turning every restriction off', async function () { + const tx = degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters(ROOT_AUTHOR_PROFILE, FIRST_PUB_ID, false, false, 0); + const txReceipt = await waitForTx(tx); + // Verifies the expected event has been emited + matchEvent( + txReceipt, + 'ModuleParametersUpdated', + [FIRST_PROFILE_ID, FIRST_PUB_ID, false, false, 0], + degreesOfSeparationReferenceModule + ); + expect( + await degreesOfSeparationReferenceModule.getModuleConfig(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.eqls([true, false, false, 0]); + }); + + it('User should be able to update module parameters using maximum valid degree of separation', async function () { + const maxDegreesOfSeparation = 4; + const tx = degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID, + true, + true, + maxDegreesOfSeparation + ); + const txReceipt = await waitForTx(tx); + // Verifies the expected event has been emited + matchEvent( + txReceipt, + 'ModuleParametersUpdated', + [FIRST_PROFILE_ID, FIRST_PUB_ID, true, true, maxDegreesOfSeparation], + degreesOfSeparationReferenceModule + ); + expect( + await degreesOfSeparationReferenceModule.getModuleConfig(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.eqls([true, true, true, maxDegreesOfSeparation]); + }); + }); + }); + + context('Update module parameters with sig', function () { + beforeEach(async function () { + await expect( + lensHub.connect(publisher).post({ + profileId: ROOT_AUTHOR_PROFILE, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: degreesOfSeparationReferenceModule.address, + referenceModuleInitData: await getDegreesOfSeparationReferenceModuleInitData({}), + }) + ).not.be.reverted; + }); + + context('Negatives', function () { + it('User should fail to update module params with sig if recovered signer does not match the expected one', async function () { + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: anotherUser, + }); + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + true, + true, + COMMENTER_PROFILE, + ownerOfCommentAuthor.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message deadline was exceeded', async function () { + const expiredDeadline = ethers.constants.One; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + deadline: expiredDeadline, + }); + expect(expiredDeadline.lt(await getTimestamp())).to.be.true; + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_EXPIRED); + }); + + it('User should fail to update module params with sig if signed message had wrong nonce', async function () { + const currentNonce = await degreesOfSeparationReferenceModule.nonces(publisher.address); + const invalidNonce = await currentNonce.add(5); + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + nonce: invalidNonce, + }); + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message domain had wrong version', async function () { + const invalidVersion = '0'; + const invalidDomain: Domain = { + name: 'DegreesOfSeparationReferenceModule', + version: invalidVersion, + chainId: chainId, + verifyingContract: degreesOfSeparationReferenceModule.address, + }; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + domain: invalidDomain, + }); + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message domain had wrong chain ID', async function () { + const invalidChainId = 69; + expect(chainId).to.not.equals(invalidChainId); + const invalidDomain: Domain = { + name: 'DegreesOfSeparationReferenceModule', + version: '1', + chainId: invalidChainId, + verifyingContract: degreesOfSeparationReferenceModule.address, + }; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + domain: invalidDomain, + }); + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message domain had wrong verifying contract', async function () { + const invalidVerifyingContract = ( + await new DegreesOfSeparationReferenceModule__factory(deployer).deploy(lensHub.address) + ).address; + const invalidDomain: Domain = { + name: 'DegreesOfSeparationReferenceModule', + version: '1', + chainId: chainId, + verifyingContract: invalidVerifyingContract, + }; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + domain: invalidDomain, + }); + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module params with sig if signed message domain had wrong name', async function () { + const invalidName = 'Degrees Of Separation Reference Module'; + const invalidDomain: Domain = { + name: invalidName, + version: '1', + chainId: chainId, + verifyingContract: degreesOfSeparationReferenceModule.address, + }; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + domain: invalidDomain, + }); + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + FIRST_PROFILE_ID, + FIRST_PUB_ID, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.SIGNATURE_INVALID); + }); + + it('User should fail to update module parameters if he does not own the profile authoring the publication', async function () { + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: anotherUser, + }); + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION, + anotherUser.address, + signature + ) + ).to.be.revertedWith(ERRORS.NOT_PROFILE_OWNER); + }); + + it('User should fail to update module parameters if the publication is not using the degrees of separation reference module', async function () { + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + pubId: FIRST_PUB_ID + 1, + }); + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID + 1, + true, + true, + DEFAULT_DEGREES_OF_SEPARATION, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.PUBLICATION_NOT_SET_UP); + }); + + it('User should fail to update module parameters if the passed degrees of separation exceeds the maximum allowed one', async function () { + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + degreesOfSeparation: 5, + }); + await expect( + degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID, + true, + true, + 5, + publisher.address, + signature + ) + ).to.be.revertedWith(ERRORS.INVALID_DEGREES_OF_SEPARATION); + }); + }); + + context('Scenarios', function () { + it('User should be able to update module parameters turning every restriction off', async function () { + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + commentsRestricted: false, + mirrorsRestricted: false, + degreesOfSeparation: 0, + }); + const tx = degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID, + false, + false, + 0, + publisher.address, + signature + ); + const txReceipt = await waitForTx(tx); + // Verifies the expected event has been emited + matchEvent( + txReceipt, + 'ModuleParametersUpdated', + [FIRST_PROFILE_ID, FIRST_PUB_ID, false, false, 0], + degreesOfSeparationReferenceModule + ); + expect( + await degreesOfSeparationReferenceModule.getModuleConfig(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.eqls([true, false, false, 0]); + }); + + it('User should be able to update module parameters using maximum valid degree of separation', async function () { + const maxDegreesOfSeparation = 4; + const signature = await signUpdateModuleParametersWithSigMessage({ + signer: publisher, + degreesOfSeparation: maxDegreesOfSeparation, + }); + const tx = degreesOfSeparationReferenceModule.updateModuleParametersWithSig( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID, + true, + true, + maxDegreesOfSeparation, + publisher.address, + signature + ); + const txReceipt = await waitForTx(tx); + // Verifies the expected event has been emited + matchEvent( + txReceipt, + 'ModuleParametersUpdated', + [FIRST_PROFILE_ID, FIRST_PUB_ID, true, true, maxDegreesOfSeparation], + degreesOfSeparationReferenceModule + ); + expect( + await degreesOfSeparationReferenceModule.getModuleConfig(FIRST_PROFILE_ID, FIRST_PUB_ID) + ).to.eqls([true, true, true, maxDegreesOfSeparation]); + }); + }); + }); + + context('Process comment', function () { + beforeEach(async function () { + await expect( + lensHub + .connect(publisher) + .follow([FIRST_DEGREE_PROFILE], [abiCoder.encode(['uint256'], [ROOT_AUTHOR_PROFILE])]) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfFirstDegreeProfile).follow([SECOND_DEGREE_PROFILE], [[]]) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfSecondDegreeProfile).follow([COMMENTER_PROFILE], [[]]) + ).to.not.be.reverted; + await expect( + lensHub.connect(publisher).post({ + profileId: ROOT_AUTHOR_PROFILE, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: degreesOfSeparationReferenceModule.address, + referenceModuleInitData: await getDegreesOfSeparationReferenceModuleInitData({}), + }) + ).not.be.reverted; + }); + + context('Negatives', function () { + it('Process comment should fail if it is not called by the hub', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(ownerOfFirstDegreeProfile) + .processComment( + FIRST_DEGREE_PROFILE, + FIRST_PROFILE_ID, + FIRST_PUB_ID, + await getDegreesOfSeparationReferenceModuleInitData({}) + ) + ).to.be.revertedWith(ERRORS.NOT_HUB); + }); + + it('User should fail to comment when degrees of separation is set as zero', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters(ROOT_AUTHOR_PROFILE, FIRST_PUB_ID, true, true, 0) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfFirstDegreeProfile).comment({ + profileId: FIRST_DEGREE_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[]]), + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.OPERATION_DISABLED); + }); + + it('User should fail to comment when passing a profile path which length exceeds the configured degrees of separation', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters(ROOT_AUTHOR_PROFILE, FIRST_PUB_ID, true, true, 1) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfSecondDegreeProfile).comment({ + profileId: SECOND_DEGREE_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[FIRST_DEGREE_PROFILE]]), + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PROFILE_PATH_EXCEEDS_DEGREES_OF_SEPARATION); + }); + + it('User should fail to comment if the owner of the root publication author does not follow the first profile in the path', async function () { + await expect( + lensHub.connect(ownerOfCommentAuthor).comment({ + profileId: COMMENTER_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[SECOND_DEGREE_PROFILE]]), + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to comment if the owner of the last profile in the path does not follow the profile authoring the comment', async function () { + await expect( + lensHub.connect(ownerOfCommentAuthor).comment({ + profileId: COMMENTER_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[FIRST_DEGREE_PROFILE]]), + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to comment if at least one of the owners of one profile in the path is not following', async function () { + const followNftAddress = await lensHub.getFollowNFT(SECOND_DEGREE_PROFILE); + await expect( + FollowNFT__factory.connect(followNftAddress, ownerOfFirstDegreeProfile).burn( + FIRST_FOLLOW_NFT_ID + ) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfCommentAuthor).comment({ + profileId: COMMENTER_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode( + ['uint256[]'], + [[FIRST_DEGREE_PROFILE, SECOND_DEGREE_PROFILE]] + ), + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to comment if passed as one degree of separation but it is not followed by the author of root publication', async function () { + await expect( + lensHub.connect(ownerOfSecondDegreeProfile).mirror({ + profileId: SECOND_DEGREE_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[]]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + }); + + context('Scenarios', function () { + it('User should be able to comment if restrictions are disabled for the comment operation', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID, + false, + true, + DEFAULT_DEGREES_OF_SEPARATION + ) + ).to.not.be.reverted; + expect(await lensHub.getFollowNFT(ROOT_AUTHOR_PROFILE)).to.equal( + ethers.constants.AddressZero + ); + await expect( + lensHub.connect(ownerOfCommentAuthor).comment({ + profileId: COMMENTER_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: [], + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('User should be able to comment if he is the exact same degrees of separation as the configured restriction from the author of root publication', async function () { + await expect( + lensHub.connect(ownerOfCommentAuthor).comment({ + profileId: COMMENTER_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode( + ['uint256[]'], + [[FIRST_DEGREE_PROFILE, SECOND_DEGREE_PROFILE]] + ), + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('User should be able to comment if he is in less degrees of separation as the configured restriction from the author of root publication', async function () { + await expect( + lensHub.connect(ownerOfSecondDegreeProfile).comment({ + profileId: SECOND_DEGREE_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[FIRST_DEGREE_PROFILE]]), + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('User should be able to comment if he is one degree of separation from the author of root publication', async function () { + await expect( + lensHub.connect(ownerOfFirstDegreeProfile).comment({ + profileId: FIRST_DEGREE_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[]]), + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('User should be able to comment if he the author of root publication', async function () { + await expect( + lensHub.connect(publisher).comment({ + profileId: ROOT_AUTHOR_PROFILE, + contentURI: MOCK_URI, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[]]), + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + }); + }); + + context('Process mirror', function () { + beforeEach(async function () { + await expect( + lensHub + .connect(publisher) + .follow([FIRST_DEGREE_PROFILE], [abiCoder.encode(['uint256'], [ROOT_AUTHOR_PROFILE])]) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfFirstDegreeProfile).follow([SECOND_DEGREE_PROFILE], [[]]) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfSecondDegreeProfile).follow([MIRRORER_PROFILE], [[]]) + ).to.not.be.reverted; + await expect( + lensHub.connect(publisher).post({ + profileId: ROOT_AUTHOR_PROFILE, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [false]), + referenceModule: degreesOfSeparationReferenceModule.address, + referenceModuleInitData: await getDegreesOfSeparationReferenceModuleInitData({}), + }) + ).not.be.reverted; + }); + + context('Negatives', function () { + it('Process mirror should fail if it is not called by the hub', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(ownerOfFirstDegreeProfile) + .processComment( + FIRST_DEGREE_PROFILE, + FIRST_PROFILE_ID, + FIRST_PUB_ID, + await getDegreesOfSeparationReferenceModuleInitData({}) + ) + ).to.be.revertedWith(ERRORS.NOT_HUB); + }); + + it('User should fail to mirror when degrees of separation is set as zero', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters(ROOT_AUTHOR_PROFILE, FIRST_PUB_ID, true, true, 0) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfFirstDegreeProfile).mirror({ + profileId: FIRST_DEGREE_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[]]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.OPERATION_DISABLED); + }); + + it('User should fail to mirror when passing a profile path which length exceeds the configured degrees of separation', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters(ROOT_AUTHOR_PROFILE, FIRST_PUB_ID, true, true, 1) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfSecondDegreeProfile).mirror({ + profileId: SECOND_DEGREE_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[FIRST_DEGREE_PROFILE]]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.PROFILE_PATH_EXCEEDS_DEGREES_OF_SEPARATION); + }); + + it('User should fail to mirror if the owner of the root publication author does not follow the first profile in the path', async function () { + await expect( + lensHub.connect(ownerOfMirrorAuthor).mirror({ + profileId: MIRRORER_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[SECOND_DEGREE_PROFILE]]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to mirror if the owner of the last profile in the path does not follow the profile authoring the mirror', async function () { + await expect( + lensHub.connect(ownerOfMirrorAuthor).mirror({ + profileId: MIRRORER_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[FIRST_DEGREE_PROFILE]]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to mirror if at least one of the owners of one profile in the path is not following', async function () { + const followNftAddress = await lensHub.getFollowNFT(SECOND_DEGREE_PROFILE); + await expect( + FollowNFT__factory.connect(followNftAddress, ownerOfFirstDegreeProfile).burn( + FIRST_FOLLOW_NFT_ID + ) + ).to.not.be.reverted; + await expect( + lensHub.connect(ownerOfMirrorAuthor).mirror({ + profileId: MIRRORER_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode( + ['uint256[]'], + [[FIRST_DEGREE_PROFILE, SECOND_DEGREE_PROFILE]] + ), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + + it('User should fail to mirror if passed as one degree of separation but it is not followed by the author of root publication', async function () { + await expect( + lensHub.connect(ownerOfSecondDegreeProfile).mirror({ + profileId: SECOND_DEGREE_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[]]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.be.revertedWith(ERRORS.FOLLOW_INVALID); + }); + }); + + context('Scenarios', function () { + it('User should be able to mirror if restrictions are disabled for the mirror operation', async function () { + await expect( + degreesOfSeparationReferenceModule + .connect(publisher) + .updateModuleParameters( + ROOT_AUTHOR_PROFILE, + FIRST_PUB_ID, + true, + false, + DEFAULT_DEGREES_OF_SEPARATION + ) + ).to.not.be.reverted; + expect(await lensHub.getFollowNFT(ROOT_AUTHOR_PROFILE)).to.equal( + ethers.constants.AddressZero + ); + await expect( + lensHub.connect(ownerOfMirrorAuthor).mirror({ + profileId: MIRRORER_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: [], + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('User should be able to mirror if he is the exact same degrees of separation as the configured restriction from the author of root publication', async function () { + await expect( + lensHub.connect(ownerOfMirrorAuthor).mirror({ + profileId: MIRRORER_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode( + ['uint256[]'], + [[FIRST_DEGREE_PROFILE, SECOND_DEGREE_PROFILE]] + ), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('User should be able to mirror if he is in less degrees of separation as the configured restriction from the author of root publication', async function () { + await expect( + lensHub.connect(ownerOfSecondDegreeProfile).mirror({ + profileId: SECOND_DEGREE_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[FIRST_DEGREE_PROFILE]]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('User should be able to mirror if he is one degree of separation from the author of root publication', async function () { + await expect( + lensHub.connect(ownerOfFirstDegreeProfile).mirror({ + profileId: FIRST_DEGREE_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[]]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + + it('User should be able to mirror if he is the author of root publication', async function () { + await expect( + lensHub.connect(publisher).mirror({ + profileId: ROOT_AUTHOR_PROFILE, + profileIdPointed: ROOT_AUTHOR_PROFILE, + pubIdPointed: FIRST_PROFILE_ID, + referenceModuleData: abiCoder.encode(['uint256[]'], [[]]), + referenceModule: ethers.constants.AddressZero, + referenceModuleInitData: [], + }) + ).to.not.be.reverted; + }); + }); + }); + }); +}); diff --git a/lens-protocol/modules/test/modules/reference/token-gated-reference-module.spec.ts b/lens-protocol/modules/test/modules/reference/token-gated-reference-module.spec.ts new file mode 100644 index 0000000..797cb4f --- /dev/null +++ b/lens-protocol/modules/test/modules/reference/token-gated-reference-module.spec.ts @@ -0,0 +1,312 @@ +import { BigNumber } from '@ethersproject/bignumber'; +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { ERRORS } from '../../helpers/errors'; +import { + lensHub, + abiCoder, + makeSuiteCleanRoom, + nft, + user, + publisher, + MOCK_PROFILE_HANDLE, + MOCK_URI, + MOCK_FOLLOW_NFT_URI, + FIRST_PROFILE_ID, + FIRST_PUB_ID, + tokenGatedReferenceModule, + freeCollectModule, + currency, + OTHER_MOCK_URI, +} from '../../__setup.spec'; +import { matchEvent, waitForTx } from '../../helpers/utils'; +import { parseEther } from '@ethersproject/units'; + +makeSuiteCleanRoom('TokenGatedReferenceModule', function () { + const SECOND_PROFILE_ID = FIRST_PROFILE_ID + 1; + + interface TokenGatedReferenceModuleInitData { + tokenAddress: string; + minThreshold: BigNumber; + } + + async function getTokenGatedReferenceModuleInitData({ + tokenAddress = nft.address, + minThreshold = BigNumber.from(1), + }: TokenGatedReferenceModuleInitData): Promise { + return abiCoder.encode(['address', 'uint256'], [tokenAddress, minThreshold]); + } + + beforeEach(async function () { + await expect( + lensHub.createProfile({ + to: publisher.address, + handle: MOCK_PROFILE_HANDLE, + imageURI: MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + await expect( + lensHub.createProfile({ + to: user.address, + handle: 'user', + imageURI: OTHER_MOCK_URI, + followModule: ethers.constants.AddressZero, + followModuleInitData: [], + followNFTURI: MOCK_FOLLOW_NFT_URI, + }) + ).to.not.be.reverted; + }); + + context('Publication creation', function () { + context('Negatives', function () { + it('User should fail to post setting zero token address', async function () { + const referenceModuleInitData = await getTokenGatedReferenceModuleInitData({ + tokenAddress: ethers.constants.AddressZero, + minThreshold: BigNumber.from(1), + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + it('User should fail to post setting zero minThreshold', async function () { + const referenceModuleInitData = await getTokenGatedReferenceModuleInitData({ + tokenAddress: currency.address, + minThreshold: ethers.constants.Zero, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID); + }); + }); + + context('Scenarios', function () { + it('User should succeed to create a publication when all parameters are valid and tx should emit expected event', async function () { + const referenceModuleInitData = await getTokenGatedReferenceModuleInitData({ + tokenAddress: currency.address, + minThreshold: BigNumber.from(1), + }); + const tx = lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }); + const txReceipt = await waitForTx(tx); + matchEvent( + txReceipt, + 'TokenGatedReferencePublicationCreated', + [FIRST_PROFILE_ID, FIRST_PUB_ID, currency.address, BigNumber.from(1)], + tokenGatedReferenceModule + ); + }); + }); + }); + + context('ERC20 Gated Reference', function () { + let referenceModuleInitData; + const minThreshold = parseEther('10'); + + beforeEach(async function () { + referenceModuleInitData = await getTokenGatedReferenceModuleInitData({ + tokenAddress: currency.address, + minThreshold, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('User should fail to mirror if they dont hold enough gating tokens', async function () { + expect(await currency.balanceOf(user.address)).to.be.lt(minThreshold); + + await expect( + lensHub.connect(user).mirror({ + profileId: SECOND_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: '0x', + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.be.revertedWith(ERRORS.NOT_ENOUGH_BALANCE); + }); + + it('User should fail to comment if they dont hold enough gating tokens', async function () { + expect(await currency.balanceOf(user.address)).to.be.lt(minThreshold); + await expect( + lensHub.connect(user).comment({ + profileId: SECOND_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: '0x', + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.be.revertedWith(ERRORS.NOT_ENOUGH_BALANCE); + }); + }); + + context('Scenarios', function () { + it('Mirroring should work if mirrorer holds enough gating tokens', async function () { + await currency.mint(user.address, minThreshold); + expect(await currency.balanceOf(user.address)).to.be.gte(minThreshold); + + await expect( + lensHub.connect(user).mirror({ + profileId: SECOND_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: '0x', + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.not.be.reverted; + }); + + it('Commenting should work if commenter holds enough gating tokens', async function () { + await currency.mint(user.address, minThreshold); + expect(await currency.balanceOf(user.address)).to.be.gte(minThreshold); + + await expect( + lensHub.connect(user).comment({ + profileId: SECOND_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: '0x', + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.not.be.reverted; + }); + }); + }); + + context('ERC721 Gated Reference', function () { + let referenceModuleInitData; + const minThreshold = BigNumber.from(1); + + beforeEach(async function () { + referenceModuleInitData = await getTokenGatedReferenceModuleInitData({ + tokenAddress: nft.address, + minThreshold, + }); + await expect( + lensHub.connect(publisher).post({ + profileId: FIRST_PROFILE_ID, + contentURI: MOCK_URI, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.not.be.reverted; + }); + + context('Negatives', function () { + it('User should fail to mirror if they dont hold enough gating tokens', async function () { + expect(await nft.balanceOf(user.address)).to.be.lt(minThreshold); + + await expect( + lensHub.connect(user).mirror({ + profileId: SECOND_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: '0x', + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.be.revertedWith(ERRORS.NOT_ENOUGH_BALANCE); + }); + + it('User should fail to comment if they dont hold enough gating tokens', async function () { + expect(await nft.balanceOf(user.address)).to.be.lt(minThreshold); + + await expect( + lensHub.connect(user).comment({ + profileId: SECOND_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: '0x', + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.be.revertedWith(ERRORS.NOT_ENOUGH_BALANCE); + }); + }); + + context('Scenarios', function () { + it('Mirroring should work if mirrorer holds enough gating tokens', async function () { + await nft.mint(user.address, 1); + + expect(await nft.balanceOf(user.address)).to.be.gte(minThreshold); + + await expect( + lensHub.connect(user).mirror({ + profileId: SECOND_PROFILE_ID, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + referenceModuleData: '0x', + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.not.be.reverted; + }); + + it('Commenting should work if commenter holds enough gating tokens', async function () { + await nft.mint(user.address, 1); + + expect(await nft.balanceOf(user.address)).to.be.gte(minThreshold); + + await expect( + lensHub.connect(user).comment({ + profileId: SECOND_PROFILE_ID, + contentURI: MOCK_URI, + profileIdPointed: FIRST_PROFILE_ID, + pubIdPointed: FIRST_PUB_ID, + collectModule: freeCollectModule.address, + collectModuleInitData: abiCoder.encode(['bool'], [true]), + referenceModuleData: '0x', + referenceModule: tokenGatedReferenceModule.address, + referenceModuleInitData: referenceModuleInitData, + }) + ).to.not.be.reverted; + }); + }); + }); +}); diff --git a/lens-protocol/modules/tsconfig.json b/lens-protocol/modules/tsconfig.json new file mode 100644 index 0000000..69e1211 --- /dev/null +++ b/lens-protocol/modules/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "outDir": "dist", + "declaration": true, + "noImplicitAny": false, + "resolveJsonModule": true + }, + "include": ["./scripts", "./test", "./typechain"], + "files": ["./hardhat.config.ts"] +} diff --git a/lens-protocol/package-lock.json b/lens-protocol/package-lock.json new file mode 100644 index 0000000..5246a74 --- /dev/null +++ b/lens-protocol/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "lens-protocol", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/lenster-main/.deepsource.toml b/lenster-main/.deepsource.toml new file mode 100644 index 0000000..bb301c3 --- /dev/null +++ b/lenster-main/.deepsource.toml @@ -0,0 +1,23 @@ +version = 1 + +exclude_patterns = [ + "node_modules", + ".next", + ".github", + ".husky", + ".vscode", + "pnpm-lock.yaml", + "packages/lens/generated.ts", + "packages/workers/snapshot-relay/generated.ts", +] + +[[analyzers]] +name = "javascript" +enabled = true + + [analyzers.meta] + plugins = ["react"] + +[[transformers]] +name = "prettier" +enabled = true diff --git a/lenster-main/.eslintrc.js b/lenster-main/.eslintrc.js new file mode 100644 index 0000000..a6fe474 --- /dev/null +++ b/lenster-main/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + settings: { + next: { + rootDir: ['apps/*/'] + } + } +}; diff --git a/lenster-main/.github/CODEOWNERS b/lenster-main/.github/CODEOWNERS new file mode 100644 index 0000000..0a9193c --- /dev/null +++ b/lenster-main/.github/CODEOWNERS @@ -0,0 +1,2 @@ +* @bigint +apps/web/src/locales/ta @bigint diff --git a/lenster-main/.github/FUNDING.yml b/lenster-main/.github/FUNDING.yml new file mode 100644 index 0000000..95721ff --- /dev/null +++ b/lenster-main/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: [lensterxyz] +custom: ['https://lenster.xyz/donate'] diff --git a/lenster-main/.github/ISSUE_TEMPLATE/bug_report.yml b/lenster-main/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..41f5c28 --- /dev/null +++ b/lenster-main/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,70 @@ +name: "Bug Report" +description: "Report a reproducible bug in the Lenster" +labels: "needs review" +body: + - type: markdown + attributes: + value: Thanks for taking the time to file a bug report! Please fill out this form as completely as possible. + + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please search to see if an issue already exists for the bug you encountered. + options: + - label: I have searched the existing issues + required: true + + - type: textarea + attributes: + label: Current Behavior + description: A concise description of what you're experiencing. + validations: + required: false + + - type: textarea + attributes: + label: Expected Behavior + description: A concise description of what you expected to happen. + validations: + required: false + + - type: textarea + attributes: + label: Steps To Reproduce + description: Steps or code snippets to reproduce the behavior. + validations: + required: false + + - type: dropdown + attributes: + label: What platform(s) does this occur on? + multiple: true + options: + - Web + - Mobile + validations: + required: true + + - type: dropdown + attributes: + label: What browser(s) does this occur on? + multiple: true + options: + - Chrome + - Firefox + - Brave + - Safari + - Edge + - Others + validations: + required: true + + - type: textarea + attributes: + label: Anything else? + description: | + Screenshots? Anything that will give us more context about the issue you are encountering! + + Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. + validations: + required: false diff --git a/lenster-main/.github/ISSUE_TEMPLATE/feature_request.yml b/lenster-main/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..2864c0f --- /dev/null +++ b/lenster-main/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,11 @@ +name: "Feature Request" +description: "Request a feature for Lenster" +labels: "needs review" +body: + - type: textarea + attributes: + label: Summary + description: Describe the feature in 1 or 2 sentences + placeholder: Clearly describe what you want to see in Lenster. + validations: + required: true diff --git a/lenster-main/.github/PULL_REQUEST_TEMPLATE.md b/lenster-main/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..2aed2a0 --- /dev/null +++ b/lenster-main/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,23 @@ +## What does this PR do? + +copilot:summary + +## Related issues + +Fixes # (issue) + +## Type of change + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Enhancement (non-breaking small changes to existing functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +## Explanation of the changes + +copilot:walkthrough + +## Emoji + +copilot:emoji diff --git a/lenster-main/.github/SECURITY.md b/lenster-main/.github/SECURITY.md new file mode 100644 index 0000000..98acf8d --- /dev/null +++ b/lenster-main/.github/SECURITY.md @@ -0,0 +1,37 @@ +# Security + +Contact: security@lenster.xyz + +At Lenster, we consider the security of our systems a top priority. But no matter how much effort we put into system security, there can still be vulnerabilities present. + +If you discover a vulnerability, we would like to know about it so we can take steps to address it as quickly as possible. We would like to ask you to help us better protect our clients and our systems. + +## Out of scope vulnerabilities: + +- Clickjacking on pages with no sensitive actions. +- Unauthenticated/logout/login CSRF. +- Attacks requiring MITM or physical access to a user's device. +- Any activity that could lead to the disruption of our service (DoS). +- Content spoofing and text injection issues without showing an attack vector/without being able to modify HTML/CSS. +- Email spoofing +- Missing DNSSEC, CAA, CSP headers +- Lack of Secure or HTTP only flag on non-sensitive cookies +- Deadlinks + +## Please do the following: + +- E-mail your findings to [security@lenster.xyz](mailto:security@lenster.xyz). +- Do not run automated scanners on our infrastructure or dashboard. If you wish to do this, contact us and we will set up a sandbox for you. +- Do not take advantage of the vulnerability or problem you have discovered, for example by downloading more data than necessary to demonstrate the vulnerability or deleting or modifying other people's data, +- Do not reveal the problem to others until it has been resolved, +- Do not use attacks on physical security, social engineering, distributed denial of service, spam or applications of third parties, +- Do provide sufficient information to reproduce the problem, so we will be able to resolve it as quickly as possible. Usually, the IP address or the URL of the affected system and a description of the vulnerability will be sufficient, but complex vulnerabilities may require further explanation. + +## What we promise: + +- We will respond to your report within 3 business days with our evaluation of the report and an expected resolution date, +- If you have followed the instructions above, we will not take any legal action against you in regard to the report, +- We will handle your report with strict confidentiality, and not pass on your personal details to third parties without your permission, +- We will keep you informed of the progress towards resolving the problem, +- In the public information concerning the problem reported, we will give your name as the discoverer of the problem (unless you desire otherwise), and +- We strive to resolve all problems as quickly as possible, and we would like to play an active role in the ultimate publication on the problem after it is resolved. diff --git a/lenster-main/.github/workflows/auto-assign.yml b/lenster-main/.github/workflows/auto-assign.yml new file mode 100644 index 0000000..b980266 --- /dev/null +++ b/lenster-main/.github/workflows/auto-assign.yml @@ -0,0 +1,23 @@ +name: Auto Assign + +on: + issues: + types: [opened] + pull_request: + types: [opened] + +jobs: + assign: + name: Assign + runs-on: macos-latest + permissions: + issues: write + pull-requests: write + steps: + - name: 'Auto-assign issue' + if: github.repository == 'lensterxyz/lenster' + uses: pozil/auto-assign-issue@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + assignees: bigint + numOfAssignee: 1 diff --git a/lenster-main/.github/workflows/ci.yml b/lenster-main/.github/workflows/ci.yml new file mode 100644 index 0000000..8d76916 --- /dev/null +++ b/lenster-main/.github/workflows/ci.yml @@ -0,0 +1,45 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + types: [opened, synchronize] + workflow_dispatch: + +jobs: + ci: + name: CI + runs-on: macos-latest + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup pnpm 🌸 + uses: pnpm/action-setup@v2.2.4 + + - name: Setup node 🍀 + uses: actions/setup-node@v3 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + + - name: Bootstrap 📦 + run: script/bootstrap + + - name: Typecheck 🔡 + run: pnpm typecheck:affected + + - name: Lint 🪩 + run: pnpm lint:affected + + - name: Prettier ✨ + run: pnpm prettier:affected + + - name: Build 🎁 + run: pnpm build + + - name: Run Tests 🧪 + run: pnpm test:e2e diff --git a/lenster-main/.github/workflows/clean-cache.yml b/lenster-main/.github/workflows/clean-cache.yml new file mode 100644 index 0000000..ddb77d4 --- /dev/null +++ b/lenster-main/.github/workflows/clean-cache.yml @@ -0,0 +1,34 @@ +name: Clean cache + +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +jobs: + cleanup: + name: Cleanup + runs-on: macos-latest + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + + - name: Cleanup ✨ + run: | + gh extension install actions/gh-actions-cache + + REPO=${{ github.repository }} + + echo "Fetching list of cache key" + cacheKeysForPR=$(gh actions-cache list -R $REPO -L 100 | cut -f 1 ) + + ## Setting this to not fail the workflow while deleting cache keys. + set +e + echo "Deleting caches..." + for cacheKey in $cacheKeysForPR + do + gh actions-cache delete $cacheKey -R $REPO --confirm + done + echo "Done" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/lenster-main/.github/workflows/crowdin-download.yml b/lenster-main/.github/workflows/crowdin-download.yml new file mode 100644 index 0000000..3246a48 --- /dev/null +++ b/lenster-main/.github/workflows/crowdin-download.yml @@ -0,0 +1,31 @@ +name: Crowdin download + +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +jobs: + download-translations: + name: Download translations + runs-on: ubuntu-latest + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + + - name: Download from Crowdin ⬇️ + uses: crowdin/github-action@v1 + with: + upload_translations: false + download_translations: true + create_pull_request: true + project_id: ${{ secrets.CROWDIN_PROJECT_ID }} + token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + pull_request_title: 'chore(i18n): synchronize translations from crowdin' + pull_request_body: 'New Crowdin pull request with translations' + pull_request_assignees: 'crowdin-bot' + pull_request_reviewers: 'bigint' + source: '/**/locales/en/*.po' + translation: '/**/locales/%two_letters_code%/%original_file_name%' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/lenster-main/.github/workflows/crowdin-upload.yml b/lenster-main/.github/workflows/crowdin-upload.yml new file mode 100644 index 0000000..28ce19b --- /dev/null +++ b/lenster-main/.github/workflows/crowdin-upload.yml @@ -0,0 +1,24 @@ +name: Crowdin upload + +on: + push: + branches: [main] + workflow_dispatch: + +jobs: + upload-translations: + name: Upload translations + runs-on: ubuntu-latest + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + + - name: Upload to Crowdin ⬆️ + uses: crowdin/github-action@v1 + with: + upload_translations: true + download_translations: false + project_id: ${{ secrets.CROWDIN_PROJECT_ID }} + token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + source: '/**/locales/en/*.po' + translation: '/**/locales/%two_letters_code%/%original_file_name%' diff --git a/lenster-main/.github/workflows/deploy-workers.yml b/lenster-main/.github/workflows/deploy-workers.yml new file mode 100644 index 0000000..d966c4d --- /dev/null +++ b/lenster-main/.github/workflows/deploy-workers.yml @@ -0,0 +1,36 @@ +name: Deploy cloudflare workers + +on: + push: + branches: [main] + workflow_dispatch: + +jobs: + deploy: + name: Deploy + runs-on: macos-latest + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup pnpm 🌸 + uses: pnpm/action-setup@v2.2.4 + + - name: Setup node 🍀 + uses: actions/setup-node@v3 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + + - name: Install 📦 + run: pnpm install --frozen-lockfile + + - name: Deploy 🚀 + run: | + pnpm add wrangler -g + pnpm workers:deploy + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} diff --git a/lenster-main/.github/workflows/i18n-extract.yml b/lenster-main/.github/workflows/i18n-extract.yml new file mode 100644 index 0000000..7fd13f1 --- /dev/null +++ b/lenster-main/.github/workflows/i18n-extract.yml @@ -0,0 +1,37 @@ +name: i18n extract + +on: + push: + branches: [main] + workflow_dispatch: + +jobs: + extract: + name: i18n extract + runs-on: macos-latest + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + with: + fetch-depth: 0 + token: ${{ secrets.BIGINT_GH_TOKEN }} + + - name: Setup pnpm 🌸 + uses: pnpm/action-setup@v2.2.4 + + - name: Setup node 🍀 + uses: actions/setup-node@v3 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + + - name: Install dependencies and extract i18n 📦 + run: | + pnpm install --frozen-lockfile + pnpm i18n:extract + + - name: Commit & Push changes 📤 + uses: actions-js/push@master + with: + message: 'chore(cron): i18n extract' + github_token: ${{ secrets.BIGINT_GH_TOKEN }} diff --git a/lenster-main/.github/workflows/push-ai-docker.yml b/lenster-main/.github/workflows/push-ai-docker.yml new file mode 100644 index 0000000..d99d0af --- /dev/null +++ b/lenster-main/.github/workflows/push-ai-docker.yml @@ -0,0 +1,34 @@ +name: Push AI Docker Image + +on: + workflow_dispatch: + push: + branches: [main] + paths: + - 'packages/ai/**' + +jobs: + push: + name: Push AI Docker Image + runs-on: macos-latest + steps: + - name: Checkout files + uses: Bhacaz/checkout-files@v2 + with: + files: packages/ai + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v4 + with: + context: packages/ai + file: packages/ai/Dockerfile + push: true + tags: yoginth/ai:latest diff --git a/lenster-main/.github/workflows/release.yml b/lenster-main/.github/workflows/release.yml new file mode 100644 index 0000000..ae5b00a --- /dev/null +++ b/lenster-main/.github/workflows/release.yml @@ -0,0 +1,20 @@ +name: Release + +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +jobs: + release: + name: Release + runs-on: macos-latest + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + with: + fetch-depth: 0 + token: ${{ secrets.BIGINT_GH_TOKEN }} + + - name: Release 🚀 + run: ./script/release diff --git a/lenster-main/.github/workflows/sync-repo.yml b/lenster-main/.github/workflows/sync-repo.yml new file mode 100644 index 0000000..717ad89 --- /dev/null +++ b/lenster-main/.github/workflows/sync-repo.yml @@ -0,0 +1,70 @@ +name: Git Repo Sync + +on: + push: + branches: [main, testnet, sandbox, staging, staging-sandbox] + +jobs: + gitlab: + runs-on: macos-latest + name: Sync to GitLab + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Push + uses: wangchucheng/git-repo-sync@v0.1.0 + with: + target-url: ${{ vars.GITLAB_URL }} + target-username: ${{ vars.GITLAB_USERNAME }} + target-token: ${{ secrets.GITLAB_SYNC_TOKEN }} + + codecommit: + runs-on: macos-latest + name: Sync to AWS CodeCommit + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Push + uses: wangchucheng/git-repo-sync@v0.1.0 + with: + target-url: ${{ vars.CODECOMMIT_URL }} + target-username: ${{ vars.CODECOMMIT_USERNAME }} + target-token: ${{ secrets.CODECOMMIT_SYNC_TOKEN }} + + codegiant: + runs-on: macos-latest + name: Sync to Codegiant + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Push + uses: wangchucheng/git-repo-sync@v0.1.0 + with: + target-url: ${{ vars.CODEGIANT_URL }} + target-username: ${{ vars.CODEGIANT_USERNAME }} + target-token: ${{ secrets.CODEGIANT_SYNC_TOKEN }} + + azure-devops: + runs-on: macos-latest + name: Sync to Azure DevOps + steps: + - name: Checkout 🚪 + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Push + uses: wangchucheng/git-repo-sync@v0.1.0 + with: + target-url: ${{ vars.AZURE_DEVOPS_URL }} + target-username: ${{ vars.AZURE_DEVOPS_USERNAME }} + target-token: ${{ secrets.AZURE_DEVOPS_SYNC_TOKEN }} diff --git a/lenster-main/.gitignore b/lenster-main/.gitignore new file mode 100644 index 0000000..567b2fc --- /dev/null +++ b/lenster-main/.gitignore @@ -0,0 +1,54 @@ +# dependencies +node_modules +.pnp +.pnp.js + +# testing +coverage + +# next.js +.next/ +out/ +.swc +build + +# misc +.DS_Store +*.pem +.eslintcache + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local +.env + +# turbo +.turbo + +# vercel +.vercel + +# typescript +*.tsbuildinfo + +# cloudflare workers +.wrangler +.dev.vars + +# playwright +.gitsigners + +# JetBrains IDE +.idea + +test-results/ +playwright-report/ +playwright/.cache/ diff --git a/lenster-main/.husky/pre-commit b/lenster-main/.husky/pre-commit new file mode 100755 index 0000000..45eed39 --- /dev/null +++ b/lenster-main/.husky/pre-commit @@ -0,0 +1,5 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +pnpm lint:affected +pnpm typecheck:affected diff --git a/lenster-main/.nvmrc b/lenster-main/.nvmrc new file mode 100644 index 0000000..3c03207 --- /dev/null +++ b/lenster-main/.nvmrc @@ -0,0 +1 @@ +18 diff --git a/lenster-main/.prettierignore b/lenster-main/.prettierignore new file mode 100644 index 0000000..2931e5e --- /dev/null +++ b/lenster-main/.prettierignore @@ -0,0 +1,3 @@ +node_modules +out +.turbo diff --git a/lenster-main/.vscode/extensions.json b/lenster-main/.vscode/extensions.json new file mode 100644 index 0000000..548539a --- /dev/null +++ b/lenster-main/.vscode/extensions.json @@ -0,0 +1,17 @@ +{ + "recommendations": [ + "esbenp.prettier-vscode", + "formulahendry.auto-close-tag", + "mikestead.dotenv", + "EditorConfig.EditorConfig", + "dbaeumer.vscode-eslint", + "GitHub.copilot-nightly", + "GitHub.remotehub", + "eamodio.gitlens", + "wix.vscode-import-cost", + "mquandalle.graphql", + "PKief.material-icon-theme", + "christian-kohler.npm-intellisense", + "bradlc.vscode-tailwindcss" + ] +} diff --git a/lenster-main/.vscode/settings.json b/lenster-main/.vscode/settings.json new file mode 100644 index 0000000..78664b2 --- /dev/null +++ b/lenster-main/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.tabSize": 2 +} diff --git a/lenster-main/CHANGELOG.md b/lenster-main/CHANGELOG.md new file mode 100644 index 0000000..c4833cf --- /dev/null +++ b/lenster-main/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Visit [releases](https://github.com/lensterxyz/lenster/releases) for full changelog. diff --git a/lenster-main/CODE_OF_CONDUCT.md b/lenster-main/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..909e77d --- /dev/null +++ b/lenster-main/CODE_OF_CONDUCT.md @@ -0,0 +1,47 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at legal@lenster.xyz. 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 + +For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq diff --git a/lenster-main/CONTRIBUTING.md b/lenster-main/CONTRIBUTING.md new file mode 100644 index 0000000..2367546 --- /dev/null +++ b/lenster-main/CONTRIBUTING.md @@ -0,0 +1,60 @@ +# Contributing to Lenster 🌸 + +👍🎉 Thank you for your interest in contributing to Lenster! 🎉👍 + +Lenster is an open-source project maintained by [Lenster team](https://github.com/lensterxyz). We appreciate your interest and efforts to contribute to Lenster. + +Anyone can be a contributor. Either you found a typo, or you have an awesome feature request you could implement, we encourage you to create a Merge Request. + +All efforts to contribute are highly appreciated, we recommend you talk to a maintainer prior to spending a lot of time making a merge request that may not align with the project roadmap. + +## Values + +- **Be the change** - Don't wait for anything, if you want something ship it but make sure it is sustainable for the long term. +- **Pride in product** - We ask ourselves whether we will use the feature if it goes live before creating it. +- **Diversity** - We welcome differences, and listen before we speak. It proportionally leads to extraordinary results and experiences. + +## Open Development & Community Driven + +Lenster is an open-source project. See the [LICENSE](https://github.com/lensterxyz/lenster/blob/main/LICENSE) file for licensing information. All the work done is available on GitHub. + +The maintainers and the contributors send merge requests which go through the same validation process. + +## Feature Requests + +Feature Requests by the community are highly encouraged. Please feel free to create an [issue](https://github.com/lensterxyz/lenster/issues/new) or to upvote 👍 [an existing issue](https://github.com/lensterxyz/lenster/issues) in the GitHub. + +## Code of Conduct + +This project and everyone participating in it are governed by the [Code of Conduct](https://github.com/lensterxyz/lenster/blob/main/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please read the [full text](https://github.com/lensterxyz/lenster/blob/main/CODE_OF_CONDUCT.md) so that you can read which actions may or may not be tolerated. + +## Bugs + +We are using [GitHub Issues](https://github.com/lensterxyz/lenster/issues) to manage our public bugs. We keep a close eye on this so before filing a new issue, try to make sure the problem does not already exist. + +--- + +## Submitting a Merge Request + +- Merge Requests should be raised for any change and it will be approved by a maintainer before merging. +- The latest changes are always in `main` branch, so please create your branch from `main`. +- If you’ve fixed a bug or added code that should be tested, add the tests and then link the corresponding issue in either your commit or your PR. +- Run `pnpm lint` before committing to make resolving conflicts easier (VSCode users, check out this extension to fix lint issues in development) +- We encourage you to test your changes, and if you have the opportunity, please make those tests part of the Merge Request. +- If you add new functionality, please provide the corresponding documentation as well and make it part of the Merge Request. +- The Merge Request should be raised against main branch. + +## Contribution Prerequisites + +- You have [Node](https://nodejs.org/en/) at >= v14. +- You are familiar with Git. + +## Development Workflow + +First of all, you need to check if you're satisfying the `Contribution Prerequisites` + +Then, please follow the instructions in [LOCAL_DEVELOPMENT_GUIDE](docs/development.md). + +--- + +## Happy Contributing 🥳 diff --git a/lenster-main/LICENSE b/lenster-main/LICENSE new file mode 100644 index 0000000..d057ea0 --- /dev/null +++ b/lenster-main/LICENSE @@ -0,0 +1,661 @@ + 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) 2023 Lenster + + 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/lenster-main/README.md b/lenster-main/README.md new file mode 100644 index 0000000..d3d888f --- /dev/null +++ b/lenster-main/README.md @@ -0,0 +1,23 @@ +# Local deployment + +- install pnpm, if needed +- from the lenster-main directory: + +- ```pnpm install``` +- ```script/bootstrap``` + +There will probably be some errors, perhaps related to Husky. If cannot be solved, try ignoring them. + +- go to subfolder ``cd apps/web`` +- create file ``.env`` from ``.env.example`` + +NB: you can also use `testnet` instead of `sandbox` in .env + +- `` cd ../..`` +- ```pnpm dev``` to start development server + +Go to http://localhost:4783/ to see the app + +More infos are available in ``/docs/development`` + +For more info about Lenster: https://github.com/lensterxyz/lenster diff --git a/lenster-main/apps/README.md b/lenster-main/apps/README.md new file mode 100644 index 0000000..a5c617f --- /dev/null +++ b/lenster-main/apps/README.md @@ -0,0 +1 @@ +# Apps diff --git a/lenster-main/apps/prerender/.env.example b/lenster-main/apps/prerender/.env.example new file mode 100644 index 0000000..2f6a0d6 --- /dev/null +++ b/lenster-main/apps/prerender/.env.example @@ -0,0 +1,3 @@ +NEXT_PUBLIC_IS_PRODUCTION=false +# mainnet, testnet, staging, sandbox or staging-sandbox +NEXT_PUBLIC_LENS_NETWORK="sandbox" diff --git a/lenster-main/apps/prerender/.eslintrc.js b/lenster-main/apps/prerender/.eslintrc.js new file mode 100644 index 0000000..8ffa6be --- /dev/null +++ b/lenster-main/apps/prerender/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@lenster/config/eslint/react.js')] +}; diff --git a/lenster-main/apps/prerender/.prettierignore b/lenster-main/apps/prerender/.prettierignore new file mode 100644 index 0000000..a680367 --- /dev/null +++ b/lenster-main/apps/prerender/.prettierignore @@ -0,0 +1 @@ +.next diff --git a/lenster-main/apps/prerender/README.md b/lenster-main/apps/prerender/README.md new file mode 100644 index 0000000..47660ee --- /dev/null +++ b/lenster-main/apps/prerender/README.md @@ -0,0 +1 @@ +# Lenster Prerender for SEO diff --git a/lenster-main/apps/prerender/next-env.d.ts b/lenster-main/apps/prerender/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/lenster-main/apps/prerender/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/lenster-main/apps/prerender/next.config.js b/lenster-main/apps/prerender/next.config.js new file mode 100644 index 0000000..a80b5ba --- /dev/null +++ b/lenster-main/apps/prerender/next.config.js @@ -0,0 +1,21 @@ +/** @type {import('next').NextConfig} */ + +const nextConfig = { + reactStrictMode: false, + trailingSlash: false, + transpilePackages: ['data'], + async headers() { + return [ + { + source: '/:path*', + headers: [ + { key: 'Access-Control-Allow-Origin', value: '*' }, + { key: 'Access-Control-Max-Age', value: '1728000' }, + { key: 'Access-Control-Allow-Headers', value: 'Content-Type' } + ] + } + ]; + } +}; + +module.exports = nextConfig; diff --git a/lenster-main/apps/prerender/package.json b/lenster-main/apps/prerender/package.json new file mode 100644 index 0000000..c97fa11 --- /dev/null +++ b/lenster-main/apps/prerender/package.json @@ -0,0 +1,35 @@ +{ + "name": "@lenster/prerender", + "version": "0.0.0", + "private": true, + "license": "AGPL-3.0", + "scripts": { + "build": "next build", + "dev": "next dev --port 4784", + "lint": "eslint . --ext .js,.ts,.tsx", + "lint:fix": "eslint . --fix --ext .js,.ts,.tsx", + "prettier": "prettier --check \"**/*.{js,ts,tsx,md}\" --cache", + "prettier:fix": "prettier --write \"**/*.{js,ts,tsx,md}\" --cache", + "start": "next start --port 4784", + "test:dev": "playwright test", + "typecheck": "tsc --pretty" + }, + "dependencies": { + "@lenster/data": "workspace:*", + "@lenster/lens": "workspace:*", + "@lenster/lib": "workspace:*", + "next": "^13.4.12", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-schemaorg": "^2.0.0", + "schema-dts": "^1.1.2" + }, + "devDependencies": { + "@lenster/config": "workspace:*", + "@lenster/lens": "workspace:*", + "@playwright/test": "^1.37.1", + "@types/react": "^18.2.21", + "@types/react-dom": "^18.2.7", + "typescript": "^5.1.6" + } +} diff --git a/lenster-main/apps/prerender/playwright.config.ts b/lenster-main/apps/prerender/playwright.config.ts new file mode 100644 index 0000000..05b4de8 --- /dev/null +++ b/lenster-main/apps/prerender/playwright.config.ts @@ -0,0 +1,19 @@ +import type { PlaywrightTestConfig } from '@playwright/test'; +import { devices } from '@playwright/test'; +import * as os from 'os'; + +const config: PlaywrightTestConfig = { + testDir: './', + timeout: 50 * 1000, + expect: { timeout: 50000 }, + fullyParallel: true, + maxFailures: 3, + forbidOnly: Boolean(process.env.CI), + retries: 3, + workers: os.cpus().length === 1 ? 1 : os.cpus().length - 1, + reporter: 'list', + use: { actionTimeout: 0, trace: 'on-first-retry' }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }] +}; + +export default config; diff --git a/lenster-main/apps/prerender/src/components/Profile.tsx b/lenster-main/apps/prerender/src/components/Profile.tsx new file mode 100644 index 0000000..7964875 --- /dev/null +++ b/lenster-main/apps/prerender/src/components/Profile.tsx @@ -0,0 +1,160 @@ +import type { MediaSet, NftImage, Publication } from '@lenster/lens'; +import { Profile } from '@lenster/lens'; +import formatHandle from '@lenster/lib/formatHandle'; +import getStampFyiURL from '@lenster/lib/getStampFyiURL'; +import sanitizeDStorageUrl from '@lenster/lib/sanitizeDStorageUrl'; +import truncateByWords from '@lenster/lib/truncateByWords'; +import type { FC } from 'react'; +import { JsonLd } from 'react-schemaorg'; +import { BASE_URL } from 'src/constants'; + +import DefaultTags from './Shared/DefaultTags'; +import SinglePublication from './Shared/SinglePublication'; +import Tags from './Shared/Tags'; + +interface ProfileProps { + profile: Profile & { picture: MediaSet & NftImage }; + publications: Publication[]; +} + +const Profile: FC = ({ profile, publications }) => { + if (!profile) { + return ; + } + + const title = profile?.name + ? `${profile?.name} (@${profile?.handle}) • Lenster` + : `@${profile?.handle} • Lenster`; + const description = truncateByWords(profile?.bio ?? '', 30); + const image = sanitizeDStorageUrl( + profile?.picture?.original?.url ?? + profile?.picture?.uri ?? + getStampFyiURL(profile?.ownedBy) + ); + + return ( + <> + + item={{ + '@context': 'https://schema.org', + '@type': 'ProfilePage', + author: { + '@type': 'Person', + additionalName: profile.handle, + description: profile.bio, + givenName: profile.name ?? profile.handle, + identifier: profile.id, + image: { + '@type': 'ImageObject', + contentUrl: image, + thumbnailUrl: image + }, + interactionStatistic: [ + { + '@type': 'InteractionCounter', + interactionType: 'https://schema.org/FollowAction', + name: 'Follows', + userInteractionCount: profile.stats.totalFollowers + }, + { + '@type': 'InteractionCounter', + interactionType: 'https://schema.org/SubscribeAction', + name: 'Following', + userInteractionCount: profile.stats.totalFollowing + }, + { + '@type': 'InteractionCounter', + interactionType: 'https://schema.org/WriteAction', + name: 'Posts', + userInteractionCount: profile.stats.totalPosts + } + ], + url: `https://lenster.xyz/u/${profile.handle}}` + } + }} + /> + } + /> +
+ {`@${formatHandle(profile.handle)}'s +

{profile.name ?? profile.handle}

+

@{formatHandle(profile.handle)}

+

+ {truncateByWords(profile?.bio ?? '', 30)} +

+
+
{profile.stats.totalPosts} Posts
+
{profile.stats.totalComments} Replies
+
{profile.stats.totalFollowing} Following
+
{profile.stats.totalFollowers} Followers
+
{profile.stats.totalMirrors} Mirrors
+
+
+ +
+
+
+ {publications?.map((publication) => { + const { __typename } = publication; + return ( +
+ +
+ ); + })} +
+ + ); +}; + +export default Profile; diff --git a/lenster-main/apps/prerender/src/components/Publication.tsx b/lenster-main/apps/prerender/src/components/Publication.tsx new file mode 100644 index 0000000..141b69c --- /dev/null +++ b/lenster-main/apps/prerender/src/components/Publication.tsx @@ -0,0 +1,75 @@ +import { DEFAULT_OG } from '@lenster/data/constants'; +import type { Comment } from '@lenster/lens'; +import { Publication } from '@lenster/lens'; +import getStampFyiURL from '@lenster/lib/getStampFyiURL'; +import sanitizeDStorageUrl from '@lenster/lib/sanitizeDStorageUrl'; +import truncateByWords from '@lenster/lib/truncateByWords'; +import type { FC } from 'react'; +import { BASE_URL } from 'src/constants'; + +import DefaultTags from './Shared/DefaultTags'; +import SinglePublication from './Shared/SinglePublication'; +import Tags from './Shared/Tags'; + +interface PublicationProps { + publication: Publication; + comments: Comment[]; +} + +const Publication: FC = ({ publication, comments }) => { + if (!publication) { + return ; + } + + const { metadata, __typename } = publication; + const hasMedia = metadata?.media.length; + const profile: any = + __typename === 'Mirror' + ? publication?.mirrorOf?.profile + : publication.profile; + const title = `${ + __typename === 'Post' + ? 'Post' + : __typename === 'Mirror' + ? 'Mirror' + : 'Comment' + } by @${publication.profile.handle} • Lenster`; + const description = truncateByWords(metadata?.content, 30); + const image = hasMedia + ? sanitizeDStorageUrl(metadata?.media[0].original.url) + : profile + ? sanitizeDStorageUrl( + profile?.picture?.original?.url ?? + profile?.picture?.uri ?? + getStampFyiURL(profile?.ownedBy) + ) + : DEFAULT_OG; + + return ( + <> + +
+ +
+
+ {comments?.map((comment) => { + const { id } = comment; + return ( +
+ +
+ ); + })} +
+ + ); +}; + +export default Publication; diff --git a/lenster-main/apps/prerender/src/components/Shared/DefaultTags.tsx b/lenster-main/apps/prerender/src/components/Shared/DefaultTags.tsx new file mode 100644 index 0000000..f61026a --- /dev/null +++ b/lenster-main/apps/prerender/src/components/Shared/DefaultTags.tsx @@ -0,0 +1,21 @@ +import { APP_NAME, DEFAULT_OG, DESCRIPTION } from '@lenster/data/constants'; +import type { FC } from 'react'; +import { BASE_URL } from 'src/constants'; + +import Tags from './Tags'; + +const DefaultTags: FC = () => { + return ( + <> + +
{APP_NAME}
+ + ); +}; + +export default DefaultTags; diff --git a/lenster-main/apps/prerender/src/components/Shared/SinglePublication.tsx b/lenster-main/apps/prerender/src/components/Shared/SinglePublication.tsx new file mode 100644 index 0000000..39eccf7 --- /dev/null +++ b/lenster-main/apps/prerender/src/components/Shared/SinglePublication.tsx @@ -0,0 +1,100 @@ +import type { Publication } from '@lenster/lens'; +import formatHandle from '@lenster/lib/formatHandle'; +import getStampFyiURL from '@lenster/lib/getStampFyiURL'; +import sanitizeDStorageUrl from '@lenster/lib/sanitizeDStorageUrl'; +import truncateByWords from '@lenster/lib/truncateByWords'; +import type { FC } from 'react'; +import { BASE_URL } from 'src/constants'; + +interface PublicationProps { + publication: Publication; + h1Content?: boolean; +} + +const SinglePublication: FC = ({ + publication, + h1Content = false +}) => { + const { id, stats, metadata, __typename } = publication; + const hasMedia = metadata?.media.length; + const isMirror = __typename === 'Mirror'; + const profile: any = isMirror + ? publication?.mirrorOf?.profile + : publication?.profile; + const publicationId = isMirror ? publication?.mirrorOf?.id : id; + const avatar = sanitizeDStorageUrl( + profile.picture?.original?.url ?? + profile.picture?.uri ?? + getStampFyiURL(profile?.ownedBy) + ); + const attachment = hasMedia + ? sanitizeDStorageUrl(metadata?.media[0].original.url) + : null; + const content = truncateByWords(metadata?.content, 30); + + // Stats + const commentsCount = isMirror + ? publication.mirrorOf.stats.totalAmountOfComments + : stats.totalAmountOfComments; + const likesCount = isMirror + ? publication.mirrorOf.stats.totalUpvotes + : stats.totalUpvotes; + const collectsCount = isMirror + ? publication.mirrorOf.stats.totalAmountOfCollects + : stats.totalAmountOfCollects; + const mirrorsCount = isMirror + ? publication.mirrorOf.stats.totalAmountOfMirrors + : stats.totalAmountOfMirrors; + + return ( + <> +
+ + {`@${formatHandle(profile.handle)}'s + +
+
+ + + {h1Content ? ( +

+ {content ?? ''} +

+ ) : ( + + )} + {attachment ? ( +
+ attachment +
+ ) : null} +
+
+
{commentsCount} Comments
+
{likesCount} Likes
+ {publication.collectModule.__typename !== + 'RevertCollectModuleSettings' ? ( +
{collectsCount} Collects
+ ) : null} +
{mirrorsCount} Mirrors
+
+
+ + ); +}; + +export default SinglePublication; diff --git a/lenster-main/apps/prerender/src/components/Shared/Tags.tsx b/lenster-main/apps/prerender/src/components/Shared/Tags.tsx new file mode 100644 index 0000000..11e54fe --- /dev/null +++ b/lenster-main/apps/prerender/src/components/Shared/Tags.tsx @@ -0,0 +1,62 @@ +import Head from 'next/head'; +import type { FC } from 'react'; + +interface TagsProps { + title: string; + description: string; + image: string; + cardType?: 'summary' | 'summary_large_image'; + schema?: any; + url: string; + publishedTime?: string; +} + +const Tags: FC = ({ + title, + description, + image, + cardType = 'summary', + schema, + url, + publishedTime +}) => { + return ( + + {title} + + + + + {/* General OG */} + + + + + + + + + {/* Twitter OG */} + + + + + + + + + {/* Lens OG */} + + + + + + {publishedTime ? ( + + ) : null} + {schema ? schema : null} + + ); +}; + +export default Tags; diff --git a/lenster-main/apps/prerender/src/constants.ts b/lenster-main/apps/prerender/src/constants.ts new file mode 100644 index 0000000..096138c --- /dev/null +++ b/lenster-main/apps/prerender/src/constants.ts @@ -0,0 +1,5 @@ +import { IS_MAINNET } from '@lenster/data/constants'; + +export const BASE_URL = IS_MAINNET + ? 'https://lenster.xyz' + : 'https://testnet.lenster.xyz'; diff --git a/lenster-main/apps/prerender/src/pages/_app.tsx b/lenster-main/apps/prerender/src/pages/_app.tsx new file mode 100644 index 0000000..a22c356 --- /dev/null +++ b/lenster-main/apps/prerender/src/pages/_app.tsx @@ -0,0 +1,7 @@ +import type { AppProps } from 'next/app'; + +const App = ({ Component, pageProps }: AppProps) => { + return ; +}; + +export default App; diff --git a/lenster-main/apps/prerender/src/pages/index.tsx b/lenster-main/apps/prerender/src/pages/index.tsx new file mode 100644 index 0000000..6621d60 --- /dev/null +++ b/lenster-main/apps/prerender/src/pages/index.tsx @@ -0,0 +1,7 @@ +import type { NextPage } from 'next'; + +const Home: NextPage = () => { + return
Prerender App
; +}; + +export default Home; diff --git a/lenster-main/apps/prerender/src/pages/posts/[id].tsx b/lenster-main/apps/prerender/src/pages/posts/[id].tsx new file mode 100644 index 0000000..16360ab --- /dev/null +++ b/lenster-main/apps/prerender/src/pages/posts/[id].tsx @@ -0,0 +1,67 @@ +import Publication from '@components/Publication'; +import { + CommentFeedDocument, + CommentOrderingTypes, + CommentRankingFilter, + CustomFiltersTypes, + PublicationDocument +} from '@lenster/lens'; +import { lensApolloNodeClient } from '@lenster/lens/apollo'; +import type { GetServerSidePropsContext } from 'next'; + +export const config = { + unstable_runtimeJS: false +}; + +export async function getServerSideProps(context: GetServerSidePropsContext) { + const id = context.params?.id; + + // Cache the response for 60 days + context.res.setHeader('Cache-Control', 'public, max-age=5184000'); + + if (!id) { + return { + props: { data: null } + }; + } + + const { data: publicationData } = await lensApolloNodeClient.query({ + query: PublicationDocument, + variables: { request: { publicationId: id } } + }); + + if (publicationData.publication) { + const profileId = null; + const reactionRequest = { profileId }; + const { publication } = publicationData; + const id = + publication.__typename === 'Mirror' + ? publication.mirrorOf.id + : publication.id; + + const { data: commentsData } = await lensApolloNodeClient.query({ + query: CommentFeedDocument, + variables: { + request: { + commentsOf: id, + customFilters: [CustomFiltersTypes.Gardeners], + commentsOfOrdering: CommentOrderingTypes.Ranking, + commentsRankingFilter: CommentRankingFilter.Relevant, + limit: 30 + }, + reactionRequest, + profileId + } + }); + + return { + props: { publication, comments: commentsData.publications?.items } + }; + } + + return { + props: { publication: null, comments: null } + }; +} + +export default Publication; diff --git a/lenster-main/apps/prerender/src/pages/u/[handle].tsx b/lenster-main/apps/prerender/src/pages/u/[handle].tsx new file mode 100644 index 0000000..70b3713 --- /dev/null +++ b/lenster-main/apps/prerender/src/pages/u/[handle].tsx @@ -0,0 +1,69 @@ +import Profile from '@components/Profile'; +import { HANDLE_SUFFIX, LENSPROTOCOL_HANDLE } from '@lenster/data/constants'; +import { + CustomFiltersTypes, + ProfileDocument, + ProfileFeedDocument +} from '@lenster/lens'; +import { lensApolloNodeClient } from '@lenster/lens/apollo'; +import type { GetServerSidePropsContext } from 'next'; + +export const config = { + unstable_runtimeJS: false +}; + +export async function getServerSideProps(context: GetServerSidePropsContext) { + const handle = context.params?.handle; + + // Cache the response for 60 days + context.res.setHeader('Cache-Control', 'public, max-age=5184000'); + + if (!handle) { + return { + props: { data: null } + }; + } + + let processedHandle; + if (handle.includes(HANDLE_SUFFIX)) { + processedHandle = handle; + } else { + processedHandle = + handle === LENSPROTOCOL_HANDLE ? handle : handle.concat(HANDLE_SUFFIX); + } + const { data: profileData } = await lensApolloNodeClient.query({ + query: ProfileDocument, + variables: { request: { handle: processedHandle } } + }); + + if (profileData.profile) { + const profileId = profileData.profile.id; + const reactionRequest = { profileId }; + + const { data: profilePublicationsData } = await lensApolloNodeClient.query({ + query: ProfileFeedDocument, + variables: { + request: { + profileId, + customFilters: [CustomFiltersTypes.Gardeners], + limit: 30 + }, + reactionRequest, + profileId + } + }); + + return { + props: { + profile: profileData.profile, + publications: profilePublicationsData.publications?.items + } + }; + } + + return { + props: { profile: null, publications: null } + }; +} + +export default Profile; diff --git a/lenster-main/apps/prerender/tests/constants.ts b/lenster-main/apps/prerender/tests/constants.ts new file mode 100644 index 0000000..19a9a03 --- /dev/null +++ b/lenster-main/apps/prerender/tests/constants.ts @@ -0,0 +1 @@ +export const PRERENDER_BASE_URL = 'http://localhost:4784'; diff --git a/lenster-main/apps/prerender/tests/profile.spec.ts b/lenster-main/apps/prerender/tests/profile.spec.ts new file mode 100644 index 0000000..1781477 --- /dev/null +++ b/lenster-main/apps/prerender/tests/profile.spec.ts @@ -0,0 +1,29 @@ +import { APP_NAME } from '@lenster/data/constants'; +import { expect, test } from '@playwright/test'; +import { PRERENDER_BASE_URL } from 'tests/constants'; + +test.beforeEach(async ({ page }) => { + await page.goto(`${PRERENDER_BASE_URL}/u/yoginth`); +}); + +test('should have page title', async ({ page }) => { + await expect(page).toHaveTitle(`Yoginth (@yoginth.lens) • ${APP_NAME}`); +}); + +test('should have name', async ({ page }) => { + await expect(page.getByTestId('profile-name')).toContainText('Yoginth'); +}); + +test('should have handle', async ({ page }) => { + await expect(page.getByTestId('profile-handle')).toContainText('@yoginth'); +}); + +test('should have bio', async ({ page }) => { + await expect(page.getByTestId('profile-bio')).toContainText( + 'opinions are mine' + ); +}); + +test('should have feed', async ({ page }) => { + await expect(page.getByTestId('profile-feed')).toBeVisible(); +}); diff --git a/lenster-main/apps/prerender/tests/publication.spec.ts b/lenster-main/apps/prerender/tests/publication.spec.ts new file mode 100644 index 0000000..10ab4bc --- /dev/null +++ b/lenster-main/apps/prerender/tests/publication.spec.ts @@ -0,0 +1,21 @@ +import { APP_NAME } from '@lenster/data/constants'; +import { expect, test } from '@playwright/test'; +import { PRERENDER_BASE_URL } from 'tests/constants'; + +test.beforeEach(async ({ page }) => { + await page.goto(`${PRERENDER_BASE_URL}/posts/0x0d-0x01`); +}); + +test('should have page title', async ({ page }) => { + await expect(page).toHaveTitle(`Post by @yoginth.lens • ${APP_NAME}`); +}); + +test('should have publication', async ({ page }) => { + await expect(page.getByTestId('publication-0x0d-0x01')).toContainText( + 'gm frens 👋' + ); +}); + +test('should have comment feed', async ({ page }) => { + await expect(page.getByTestId('comment-feed')).toBeVisible(); +}); diff --git a/lenster-main/apps/prerender/tsconfig.json b/lenster-main/apps/prerender/tsconfig.json new file mode 100644 index 0000000..3ae87b2 --- /dev/null +++ b/lenster-main/apps/prerender/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@lenster/config/react.tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@components*": ["src/components*"], + "@lib*": ["src/lib*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"] +} diff --git a/lenster-main/apps/web/.env.example b/lenster-main/apps/web/.env.example new file mode 100644 index 0000000..5b1aba9 --- /dev/null +++ b/lenster-main/apps/web/.env.example @@ -0,0 +1,3 @@ +NEXT_PUBLIC_IS_PRODUCTION=false +NEXT_PUBLIC_LENS_NETWORK="sandbox" # "mainnet" or "sandbox" +NEXT_PUBLIC_SENTRY_DSN="" diff --git a/lenster-main/apps/web/.eslintrc.js b/lenster-main/apps/web/.eslintrc.js new file mode 100644 index 0000000..8ffa6be --- /dev/null +++ b/lenster-main/apps/web/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@lenster/config/eslint/react.js')] +}; diff --git a/lenster-main/apps/web/.gitignore b/lenster-main/apps/web/.gitignore new file mode 100644 index 0000000..fcfbb80 --- /dev/null +++ b/lenster-main/apps/web/.gitignore @@ -0,0 +1,4 @@ +src/locales/**/*.js + +# Sentry Auth Token +.sentryclirc diff --git a/lenster-main/apps/web/.prettierignore b/lenster-main/apps/web/.prettierignore new file mode 100644 index 0000000..f2bbf70 --- /dev/null +++ b/lenster-main/apps/web/.prettierignore @@ -0,0 +1,2 @@ +.next +src/locales diff --git a/lenster-main/apps/web/README.md b/lenster-main/apps/web/README.md new file mode 100644 index 0000000..572b207 --- /dev/null +++ b/lenster-main/apps/web/README.md @@ -0,0 +1 @@ +# Lenster Web diff --git a/lenster-main/apps/web/lingui.config.js b/lenster-main/apps/web/lingui.config.js new file mode 100644 index 0000000..4b9c3d4 --- /dev/null +++ b/lenster-main/apps/web/lingui.config.js @@ -0,0 +1,20 @@ +/** @type {import('@lingui/conf').LinguiConfig} */ +module.exports = { + format: 'po', + orderBy: 'origin', + locales: ['en', 'zh', 'fr', 'ru', 'ta'], + sourceLocale: 'en', + catalogs: [ + { + path: 'src/locales/{locale}/messages', + include: ['src'] + } + ], + fallbackLocales: { + default: 'en' + }, + formatOptions: { + origins: true, + lineNumbers: false + } +}; diff --git a/lenster-main/apps/web/next-env.d.ts b/lenster-main/apps/web/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/lenster-main/apps/web/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/lenster-main/apps/web/next.config.js b/lenster-main/apps/web/next.config.js new file mode 100644 index 0000000..267ab92 --- /dev/null +++ b/lenster-main/apps/web/next.config.js @@ -0,0 +1,87 @@ +const { withSentryConfig } = require('@sentry/nextjs'); + +const headers = [{ key: 'Cache-Control', value: 'public, max-age=3600' }]; + +/** @type {import('next').NextConfig} */ +const nextConfig = { + transpilePackages: ['data'], + reactStrictMode: false, + experimental: { + scrollRestoration: true, + newNextLinkBehavior: true, + swcPlugins: [['@lingui/swc-plugin', {}]] + }, + async rewrites() { + return [ + { + source: '/sitemap.xml', + destination: 'https://sitemap.lenster.xyz/sitemap.xml' + }, + { + source: '/sitemaps/:match*', + destination: 'https://sitemap.lenster.xyz/:match*' + } + ]; + }, + async redirects() { + return [ + { + source: '/u/:handle(.+).lens', + destination: '/u/:handle', + permanent: true + }, + { + source: '/u/:handle(.+).test', + destination: '/u/:handle', + permanent: true + }, + { + source: '/discord', + destination: 'https://discord.com/invite/B8eKhSSUwX', + permanent: true + }, + { + source: '/donate', + destination: 'https://giveth.io/project/lenster?utm_source=lenster', + permanent: true + }, + { + source: '/gitcoin', + destination: + 'https://explorer.gitcoin.co/#/round/10/0x8de918f0163b2021839a8d84954dd7e8e151326d/0x8de918f0163b2021839a8d84954dd7e8e151326d-2', + permanent: true + } + ]; + }, + async headers() { + return [ + { + source: '/(.*)', + headers: [ + { key: 'X-Content-Type-Options', value: 'nosniff' }, + { key: 'X-XSS-Protection', value: '1; mode=block' }, + { key: 'Referrer-Policy', value: 'strict' } + ] + }, + { source: '/about', headers }, + { source: '/privacy', headers }, + { source: '/thanks', headers } + ]; + } +}; + +module.exports = withSentryConfig( + nextConfig, + { + silent: true, + org: 'lenster', + project: 'web' + }, + { + widenClientFileUpload: true, + transpileClientSDK: true, + tunnelRoute: '/monitoring', + hideSourceMaps: true, + disableLogger: true + } +); diff --git a/lenster-main/apps/web/package.json b/lenster-main/apps/web/package.json new file mode 100644 index 0000000..fd9a2db --- /dev/null +++ b/lenster-main/apps/web/package.json @@ -0,0 +1,101 @@ +{ + "name": "@lenster/web", + "version": "0.0.0", + "private": true, + "license": "AGPL-3.0", + "scripts": { + "build": "lingui compile; next build", + "dev": "lingui compile; next dev --port 4783", + "extract": "lingui compile; lingui extract", + "lint": "eslint . --ext .ts,.tsx", + "lint:fix": "eslint . --fix --ext .ts,.tsx", + "prettier": "prettier --check \"**/*.{js,ts,tsx,md}\" --cache", + "prettier:fix": "prettier --write \"**/*.{js,ts,tsx,md}\" --cache", + "start": "next start --port 4783", + "test:dev": "playwright test", + "typecheck": "tsc --pretty" + }, + "dependencies": { + "@aws-sdk/client-s3": "^3.398.0", + "@dnd-kit/core": "^6.0.8", + "@dnd-kit/sortable": "^7.0.2", + "@headlessui/react": "^1.7.17", + "@heroicons/react": "v1", + "@hookform/resolvers": "^3.3.0", + "@lens-protocol/sdk-gated": "^1.2.0", + "@lenster/abis": "workspace:*", + "@lenster/data": "workspace:*", + "@lenster/image-cropper": "workspace:*", + "@lenster/lens": "workspace:*", + "@lenster/lib": "workspace:*", + "@lenster/snapshot": "workspace:*", + "@lenster/types": "workspace:*", + "@lenster/ui": "workspace:*", + "@lexical/code": "^0.12.0", + "@lexical/hashtag": "^0.12.0", + "@lexical/link": "^0.12.0", + "@lexical/markdown": "^0.12.0", + "@lexical/react": "^0.12.0", + "@lexical/utils": "^0.12.0", + "@lingui/core": "^4.4.0", + "@lingui/detect-locale": "^4.4.0", + "@lingui/loader": "^4.4.0", + "@lingui/macro": "^4.4.0", + "@lingui/react": "^4.4.0", + "@lingui/swc-plugin": "4.0.0", + "@livepeer/react": "^2.8.0", + "@sentry/nextjs": "^7.64.0", + "@tanstack/react-query": "^4.33.0", + "@tippyjs/react": "^4.2.6", + "@xmtp/xmtp-js": "^10.2.0", + "axios": "^1.4.0", + "clsx": "^2.0.0", + "dayjs": "^1.11.9", + "dayjs-twitter": "^0.5.0", + "dexie": "^3.2.4", + "dexie-react-hooks": "^1.1.6", + "framer-motion": "^10.16.1", + "graphql": "^16.8.0", + "idb-keyval": "^6.2.1", + "lexical": "^0.12.0", + "next": "13.4.2", + "next-themes": "^0.2.1", + "plyr-react": "^5.3.0", + "rc-slider": "^10.2.1", + "react": "^18.2.0", + "react-activity-calendar": "^2.0.2", + "react-cool-inview": "^3.0.1", + "react-dom": "^18.2.0", + "react-hook-form": "^7.45.4", + "react-hot-toast": "^2.4.1", + "react-markdown": "^8.0.7", + "react-virtuoso": "^4.5.0", + "remark-breaks": "^3.0.3", + "remark-linkify-regex": "^1.2.1", + "shared-zustand": "^2.0.0", + "strip-markdown": "^5.0.1", + "use-resize-observer": "^9.1.0", + "usehooks-ts": "^2.9.1", + "uuid": "^9.0.0", + "viem": "^1.7.0", + "wagmi": "^1.3.10", + "xmtp-content-type-remote-attachment": "^1.0.7", + "zod": "^3.22.2", + "zustand": "^4.4.1" + }, + "devDependencies": { + "@lenster/config": "workspace:*", + "@lingui/cli": "^4.4.0", + "@playwright/test": "^1.37.1", + "@tailwindcss/aspect-ratio": "^0.4.2", + "@tailwindcss/forms": "^0.5.5", + "@types/node": "^20.5.4", + "@types/react": "^18.2.21", + "@types/react-dom": "^18.2.7", + "@types/uuid": "^9.0.2", + "autoprefixer": "^10.4.15", + "postcss": "^8.4.28", + "tailwindcss": "^3.3.3", + "typescript": "^5.1.6" + } +} diff --git a/lenster-main/apps/web/playwright.config.ts b/lenster-main/apps/web/playwright.config.ts new file mode 100644 index 0000000..05b4de8 --- /dev/null +++ b/lenster-main/apps/web/playwright.config.ts @@ -0,0 +1,19 @@ +import type { PlaywrightTestConfig } from '@playwright/test'; +import { devices } from '@playwright/test'; +import * as os from 'os'; + +const config: PlaywrightTestConfig = { + testDir: './', + timeout: 50 * 1000, + expect: { timeout: 50000 }, + fullyParallel: true, + maxFailures: 3, + forbidOnly: Boolean(process.env.CI), + retries: 3, + workers: os.cpus().length === 1 ? 1 : os.cpus().length - 1, + reporter: 'list', + use: { actionTimeout: 0, trace: 'on-first-retry' }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }] +}; + +export default config; diff --git a/lenster-main/apps/web/postcss.config.js b/lenster-main/apps/web/postcss.config.js new file mode 100644 index 0000000..5cbc2c7 --- /dev/null +++ b/lenster-main/apps/web/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; diff --git a/lenster-main/apps/web/public/.well-known/security.txt b/lenster-main/apps/web/public/.well-known/security.txt new file mode 100644 index 0000000..a6d081d --- /dev/null +++ b/lenster-main/apps/web/public/.well-known/security.txt @@ -0,0 +1,6 @@ +Contact: https://github.com/lensterxyz/lenster/security/advisories/new +Expires: 2022-12-31T18:29:00.000Z +Acknowledgments: https://github.com/lensterxyz/lenster/security/advisories?state=published +Preferred-Languages: en +Canonical: https://lenster.xyz/.well-known/security.txt +Policy: https://github.com/lensterxyz/lenster/security/policy diff --git a/lenster-main/apps/web/public/apple-touch-icon.png b/lenster-main/apps/web/public/apple-touch-icon.png new file mode 100644 index 0000000..7d190df Binary files /dev/null and b/lenster-main/apps/web/public/apple-touch-icon.png differ diff --git a/lenster-main/apps/web/public/assets/type-bold.svg b/lenster-main/apps/web/public/assets/type-bold.svg new file mode 100755 index 0000000..b84d940 --- /dev/null +++ b/lenster-main/apps/web/public/assets/type-bold.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/lenster-main/apps/web/public/assets/type-code.svg b/lenster-main/apps/web/public/assets/type-code.svg new file mode 100755 index 0000000..094704d --- /dev/null +++ b/lenster-main/apps/web/public/assets/type-code.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/lenster-main/apps/web/public/assets/type-italic.svg b/lenster-main/apps/web/public/assets/type-italic.svg new file mode 100755 index 0000000..a72c14c --- /dev/null +++ b/lenster-main/apps/web/public/assets/type-italic.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/lenster-main/apps/web/public/favicon-16x16.png b/lenster-main/apps/web/public/favicon-16x16.png new file mode 100644 index 0000000..5bc4d4b Binary files /dev/null and b/lenster-main/apps/web/public/favicon-16x16.png differ diff --git a/lenster-main/apps/web/public/favicon-32x32.png b/lenster-main/apps/web/public/favicon-32x32.png new file mode 100644 index 0000000..ec14d04 Binary files /dev/null and b/lenster-main/apps/web/public/favicon-32x32.png differ diff --git a/lenster-main/apps/web/public/favicon.ico b/lenster-main/apps/web/public/favicon.ico new file mode 100644 index 0000000..6c7e174 Binary files /dev/null and b/lenster-main/apps/web/public/favicon.ico differ diff --git a/lenster-main/apps/web/public/fonts/CircularXXSub-Bold.woff b/lenster-main/apps/web/public/fonts/CircularXXSub-Bold.woff new file mode 100644 index 0000000..f40a8d5 Binary files /dev/null and b/lenster-main/apps/web/public/fonts/CircularXXSub-Bold.woff differ diff --git a/lenster-main/apps/web/public/fonts/CircularXXSub-Book.woff b/lenster-main/apps/web/public/fonts/CircularXXSub-Book.woff new file mode 100644 index 0000000..7cdfc1e Binary files /dev/null and b/lenster-main/apps/web/public/fonts/CircularXXSub-Book.woff differ diff --git a/lenster-main/apps/web/public/fonts/CircularXXSub-Medium.woff b/lenster-main/apps/web/public/fonts/CircularXXSub-Medium.woff new file mode 100644 index 0000000..de2ad60 Binary files /dev/null and b/lenster-main/apps/web/public/fonts/CircularXXSub-Medium.woff differ diff --git a/lenster-main/apps/web/public/lens.png b/lenster-main/apps/web/public/lens.png new file mode 100644 index 0000000..593dc4e Binary files /dev/null and b/lenster-main/apps/web/public/lens.png differ diff --git a/lenster-main/apps/web/public/logo.svg b/lenster-main/apps/web/public/logo.svg new file mode 100644 index 0000000..316c608 --- /dev/null +++ b/lenster-main/apps/web/public/logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/lenster-main/apps/web/public/opensearch.xml b/lenster-main/apps/web/public/opensearch.xml new file mode 100644 index 0000000..e3e1e44 --- /dev/null +++ b/lenster-main/apps/web/public/opensearch.xml @@ -0,0 +1,8 @@ + + Lenster + Lenster Search + + https://lenster.xyz/favicon-32x32.png + UTF-8 + https://lenster.xyz + diff --git a/lenster-main/apps/web/public/pride.svg b/lenster-main/apps/web/public/pride.svg new file mode 100644 index 0000000..e9959e7 --- /dev/null +++ b/lenster-main/apps/web/public/pride.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lenster-main/apps/web/public/robots.txt b/lenster-main/apps/web/public/robots.txt new file mode 100644 index 0000000..4208186 --- /dev/null +++ b/lenster-main/apps/web/public/robots.txt @@ -0,0 +1,25 @@ +User-agent: Googlebot +Allow: /* +Disallow: /_next/* +Disallow: /settings/* +Disallow: /messages/* + +User-agent: Yandex +Allow: /* +Disallow: /_next/* +Disallow: /settings/* +Disallow: /messages/* + +User-agent: bingbot +Allow: /* +Disallow: /_next/* +Disallow: /settings/* +Disallow: /messages/* + +User-agent: * +Allow: /* +Disallow: /_next/* +Disallow: /settings/* +Disallow: /messages/* + +Sitemap: https://lenster.xyz/sitemap.xml diff --git a/lenster-main/apps/web/sentry.client.config.ts b/lenster-main/apps/web/sentry.client.config.ts new file mode 100644 index 0000000..1b6eee5 --- /dev/null +++ b/lenster-main/apps/web/sentry.client.config.ts @@ -0,0 +1,7 @@ +import * as Sentry from '@sentry/nextjs'; + +Sentry.init({ + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + tracesSampleRate: 1, + debug: false +}); diff --git a/lenster-main/apps/web/sentry.edge.config.ts b/lenster-main/apps/web/sentry.edge.config.ts new file mode 100644 index 0000000..1b6eee5 --- /dev/null +++ b/lenster-main/apps/web/sentry.edge.config.ts @@ -0,0 +1,7 @@ +import * as Sentry from '@sentry/nextjs'; + +Sentry.init({ + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + tracesSampleRate: 1, + debug: false +}); diff --git a/lenster-main/apps/web/sentry.server.config.ts b/lenster-main/apps/web/sentry.server.config.ts new file mode 100644 index 0000000..1b6eee5 --- /dev/null +++ b/lenster-main/apps/web/sentry.server.config.ts @@ -0,0 +1,7 @@ +import * as Sentry from '@sentry/nextjs'; + +Sentry.init({ + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + tracesSampleRate: 1, + debug: false +}); diff --git a/lenster-main/apps/web/src/components/Bookmarks/Feed.tsx b/lenster-main/apps/web/src/components/Bookmarks/Feed.tsx new file mode 100644 index 0000000..83d9cba --- /dev/null +++ b/lenster-main/apps/web/src/components/Bookmarks/Feed.tsx @@ -0,0 +1,98 @@ +import SinglePublication from '@components/Publication/SinglePublication'; +import PublicationsShimmer from '@components/Shared/Shimmer/PublicationsShimmer'; +import { BookmarkIcon } from '@heroicons/react/outline'; +import type { + Publication, + PublicationMainFocus, + PublicationsProfileBookmarkedQueryRequest +} from '@lenster/lens'; +import { usePublicationsProfileBookmarksQuery } from '@lenster/lens'; +import { Card, EmptyState, ErrorMessage } from '@lenster/ui'; +import { t } from '@lingui/macro'; +import type { FC } from 'react'; +import { useInView } from 'react-cool-inview'; +import { useAppStore } from 'src/store/app'; + +interface FeedProps { + focus?: PublicationMainFocus; +} + +const Feed: FC = ({ focus }) => { + const currentProfile = useAppStore((state) => state.currentProfile); + + // Variables + const request: PublicationsProfileBookmarkedQueryRequest = { + profileId: currentProfile?.id, + metadata: { + ...(focus && { mainContentFocus: [focus] }) + }, + limit: 10 + }; + const reactionRequest = currentProfile + ? { profileId: currentProfile?.id } + : null; + const profileId = currentProfile?.id ?? null; + + const { data, loading, error, fetchMore } = + usePublicationsProfileBookmarksQuery({ + variables: { request, reactionRequest, profileId } + }); + + const publications = data?.publicationsProfileBookmarks?.items; + const pageInfo = data?.publicationsProfileBookmarks?.pageInfo; + const hasMore = pageInfo?.next; + + const { observe } = useInView({ + onChange: async ({ inView }) => { + if (!inView || !hasMore) { + return; + } + + await fetchMore({ + variables: { + request: { ...request, cursor: pageInfo?.next }, + reactionRequest, + profileId + } + }); + } + }); + + if (loading) { + return ; + } + + if (publications?.length === 0) { + return ( + } + /> + ); + } + + if (error) { + return ( + + ); + } + + return ( + + {publications?.map((publication, index) => ( + + ))} + {hasMore ? : null} + + ); +}; + +export default Feed; diff --git a/lenster-main/apps/web/src/components/Bookmarks/index.tsx b/lenster-main/apps/web/src/components/Bookmarks/index.tsx new file mode 100644 index 0000000..7773442 --- /dev/null +++ b/lenster-main/apps/web/src/components/Bookmarks/index.tsx @@ -0,0 +1,51 @@ +import MetaTags from '@components/Common/MetaTags'; +import RecommendedProfiles from '@components/Home/RecommendedProfiles'; +import Trending from '@components/Home/Trending'; +import FeedFocusType from '@components/Shared/FeedFocusType'; +import Footer from '@components/Shared/Footer'; +import { APP_NAME } from '@lenster/data/constants'; +import { FeatureFlag } from '@lenster/data/feature-flags'; +import { PAGEVIEW } from '@lenster/data/tracking'; +import type { PublicationMainFocus } from '@lenster/lens'; +import isFeatureEnabled from '@lenster/lib/isFeatureEnabled'; +import { GridItemEight, GridItemFour, GridLayout } from '@lenster/ui'; +import { Leafwatch } from '@lib/leafwatch'; +import { t } from '@lingui/macro'; +import type { NextPage } from 'next'; +import { useState } from 'react'; +import Custom404 from 'src/pages/404'; +import { useAppStore } from 'src/store/app'; +import { useEffectOnce } from 'usehooks-ts'; + +import Feed from './Feed'; + +const Bookmarks: NextPage = () => { + const currentProfile = useAppStore((state) => state.currentProfile); + const [focus, setFocus] = useState(); + const isTrendingWidgetEnabled = isFeatureEnabled(FeatureFlag.TrendingWidget); + + useEffectOnce(() => { + Leafwatch.track(PAGEVIEW, { page: 'bookmarks' }); + }); + + if (!currentProfile) { + return ; + } + + return ( + + + + + + + + {isTrendingWidgetEnabled && } + {currentProfile ? : null} +