diff --git a/.gitignore b/.gitignore index 8f6f4993..c825ee23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,11 @@ /euler-addresses.json /euler-addresses-*.json +/euler-contracts-verification-*.json /node_modules/ /artifacts/ /cache/ +/artifacts-zk/ +/cache-zk/ /.idea/ /coverage.json /coverage/ diff --git a/addresses/euler-addresses-basetestnet.json b/addresses/euler-addresses-basetestnet.json new file mode 100644 index 00000000..64b11687 --- /dev/null +++ b/addresses/euler-addresses-basetestnet.json @@ -0,0 +1,58 @@ +{ + "tokens": { + "EUL": "0x6ad40cE1C9D3A518dCE8D89295008ECA1bf0F321", + "WETH": "0xE392Ee380A9917D08B521E9488a66C83364678d2", + "USDC": "0xe727D925Ab233273d87fAb6Da58446Ed610CEdC7", + "COMP": "0xCAF841C852132f32738eecbd0b4f5d482e16b262", + "WBTC": "0x5171Be04CdBF5e958a947f7CFED4cAb0EE0D329d" + }, + "modules": { + "installer": "0x537E3F6913D9851127f4E26401E3145684f6a433", + "markets": "0xe1DEf83bEF24f9dD5EfdCC79FF21c2a9D3D462B8", + "liquidation": "0x81E8C68CAD8BDb4F751A3a6cA78f3EC51bDc13d5", + "governance": "0xf334f61Eb92F0174AF1e54e0E74A0377050c95b0", + "exec": "0xE14B8ad1d5040495deD2CA0D21FC39c15b76a0A3", + "swap": "0xe1c9f61F8934A9Ac2a84a47cde5662b141D5e940", + "swapHub": "0xeF41850794021D5C95504Ea2b748E6819A79d776", + "eToken": "0x4aC1d1ba6325F3b0B210De5Ea0e7F8c54A7676B1", + "dToken": "0x98A9728262558BbBbD18921Be51b0Ee0CD7d21B6", + "riskManager": "0x3BBC61d81035eD583fFb675d230eECb30D934Fde", + "irmDefault": "0xdE76ccBae10010116fCA4dc92A6AacA5918c0FDb", + "irmZero": "0x93eD364a685c26c55b0Dd8da9baBDf62aF8792C2", + "irmFixed": "0x46B5cC46EA4954Def036F8eD261b0Da6eD0E9F35", + "irmLinear": "0x0fdd3Ba574f728A32550334Ed1F09545dE05A8c0" + }, + "chainlinkCompatOracles": { + "EUL": "0x90E644678b43399659010DD07259ED61E372ddb5", + "WETH": "0x1231343C8595FC2Da9C16F871e000fa69B68b9b8", + "USDC": "0xCb8Ca7100Cf883769364BAd2324E710E8C17c96f", + "COMP": "0x7A9921787a89A49c828667CaA7BBE48010B65D33", + "WBTC": "0xD3f45CD686167F81a3a17Cf6Ec95cF14F13be70C" + }, + "swapHandlers": { + "swapHandlerUniswapV3": "0x38455c5c800af093789353b183E36B2b0BeC0876", + "swapHandler1Inch": "0x61e0F68EcDCb9E7937Ebd2FCAba3f03601500C02", + "swapHandlerUniAutoRouter": "0x040bEEaC03a1A6BD2E7451Cf05b3f943A947eBFf" + }, + "uniswapV3Factory": "0x161a51ff21Bf7dCEb17Be5A4D4F5F1fe8DdEbB33", + "invariantChecker": "0xdb4B1ccdD88e7e93c2A17bF4e3f270a61189B3E9", + "flashLoanNativeTest": "0x83a4bA59679fD4D5a92cB6692b4CDA5E3A1765D6", + "flashLoanAdaptorTest": "0xeE0CF99D092f46D5c2D4446f4b3A8CC72aDEDc55", + "flashLoanAdaptorTest2": "0x324219113D289836554748D24946C962eA4a1b62", + "simpleUniswapPeriphery": "0x6c53375FcEA59412f406E007F5a212E92B651db4", + "euler": "0x18b88C623525909B59BC5f537f03F8f08e9a1823", + "eulerSimpleLens": "0xA2a2f0381e7EdE59053ef123d629b228E641677B", + "deltaBalances": "0xcFd58C5B2A340b2eB1BCf27904a2f406E9f2d3F8", + "eulerGeneralView": "0x251835998B36706e9D2c9A105f2acC4b2Ad73FEa", + "installer": "0x7E3498E8C350F90C6Da1197f48d41F14A817Be09", + "markets": "0x6f6404301D5143C319a81508291A8799370E1829", + "liquidation": "0xe4764E5D4A23C344A22bf0Ba518992666f9D0c5E", + "governance": "0xFbBf16Cb3c98EF58463B7e7693f71aaE84c5f4c9", + "exec": "0x28F980c522D463905eE7F55e4A3c8001cAb3A848", + "swap": "0x8834CEfEc3968a82C5B084B936a47D8c26f0e87F", + "swapHub": "0x00E8Ba61516E8FD2373bcc5cC015088323fA62fE", + "flashLoan": "0x0E02AE5a5Cddd2eD61541f1a3DA39e81E15aea6e", + "testERC20TokenFaucet": "0x427Dc179e9Aabbf890322c88B5b7eCB449D7a224", + "eulStakes": "0x380F43Fee8a1D30B2FFf3e1Bea84366c72064954", + "eulDistributor": "0x37987fE00Ec11dCE3767328188C28fd06F38b8A7" +} diff --git a/addresses/euler-addresses-bsctestnet.json b/addresses/euler-addresses-bsctestnet.json new file mode 100644 index 00000000..2e283e98 --- /dev/null +++ b/addresses/euler-addresses-bsctestnet.json @@ -0,0 +1,54 @@ +{ + "tokens": { + "WETH": "0x594a6993bB7A533132D65001a7C99fC66Fae38F4", + "EUL": "0x427Dc179e9Aabbf890322c88B5b7eCB449D7a224", + "USDT": "0x69632F2DB366e9Af8fdb767F674B0F0e4Da812C6", + "USDC": "0x8682B60F3dBaa29343D60c94D26CacdC0469Ed72", + "COMP": "0x3BBC61d81035eD583fFb675d230eECb30D934Fde", + "WBTC": "0x2d5C5c1be18a9B17A15D82575d895eC14B3d3549" + }, + "modules": { + "installer": "0x93eD364a685c26c55b0Dd8da9baBDf62aF8792C2", + "markets": "0x46B5cC46EA4954Def036F8eD261b0Da6eD0E9F35", + "liquidation": "0x0fdd3Ba574f728A32550334Ed1F09545dE05A8c0", + "governance": "0x18b88C623525909B59BC5f537f03F8f08e9a1823", + "exec": "0xB0CEab555018312E427a3A45dCF549a048eE4B2E", + "swap": "0x251835998B36706e9D2c9A105f2acC4b2Ad73FEa", + "swapHub": "0x055CF59b5A3dd359b1c75D29C2Cb458c4fb04423", + "eToken": "0x38455c5c800af093789353b183E36B2b0BeC0876", + "dToken": "0x61e0F68EcDCb9E7937Ebd2FCAba3f03601500C02", + "riskManager": "0xd50F2D27d3CD53B6db360C30109FA421e49a42F2", + "irmDefault": "0x1d827FD7D55A246BE9975a3fDbba3a56B22Ddf44", + "irmZero": "0x19890FD87E13B2c09a5acD14Ffe7140Aa9A7b832", + "irmFixed": "0x299fBf933d9A2e92C641024cb324cF5bbbC6009e", + "irmLinear": "0x4DE6cbDd830b55b53334dE6D6DC77f6388c206db" + }, + "chainlinkCompatOracles": { + "EUL": "0x380f43fee8a1d30b2fff3e1bea84366c72064954", + "USDT": "0xcfd58c5b2a340b2eb1bcf27904a2f406e9f2d3f8", + "USDC": "0x4bb4683355a8e5f505cc27f7dbdd4e30aaf2c5c1", + "WETH": "0x5171Be04CdBF5e958a947f7CFED4cAb0EE0D329d", + "COMP": "0xDdA8F0A53Dcdee94fD47079cf7e93e8Cf14aB55F", + "WBTC": "0xBc106Dec2E349EEF69D74bBc6b796b48941A5c49" + }, + "swapHandlers": {}, + "uniswapV3Factory": "0xe1c9f61F8934A9Ac2a84a47cde5662b141D5e940", + "invariantChecker": "0xeF41850794021D5C95504Ea2b748E6819A79d776", + "flashLoanNativeTest": "0x4aC1d1ba6325F3b0B210De5Ea0e7F8c54A7676B1", + "flashLoanAdaptorTest": "0x98A9728262558BbBbD18921Be51b0Ee0CD7d21B6", + "flashLoanAdaptorTest2": "0x0c813db988F760a6df9d6fa93fDe00e8F0d8d742", + "simpleUniswapPeriphery": "0xdE76ccBae10010116fCA4dc92A6AacA5918c0FDb", + "euler": "0x107c312Cd380e4d981809278a91f920C16d9d137", + "eulerSimpleLens": "0x7Dbd4D9eb53456360725DAC1FB6Dc0E86DEdf6CF", + "deltaBalances": "0xaF8a17B70062c3fA679f8241325C003a72a3a826", + "eulerGeneralView": "0x9150646E7229282A9fA1527Eb1bA356eB0F228E9", + "installer": "0x3E3c31700AB692416D08462F895A5b212Ae66cC1", + "markets": "0xbd60ad653F3B6b210f28E4D906C998626371579D", + "liquidation": "0x7a19E978A9bE334A8b26b4c7bE6CE6Ce04481152", + "governance": "0xac1e53ac6e6444DC1842BafFdD7E1D7CcFaf886a", + "exec": "0x0Cfd331692F44aa6C488f35FA71fFFBf5Ffe3719", + "swap": "0x22093cC59D9BA0c7380B8a88AF0578E9ad735d80", + "eulStakes": "0xBd6DEC1Da22d3385E7Bb07494aa2DF38C7da2E1F", + "eulDistributor": "0x733F408cC826140f64c3106C51A236D0f3E3fa28", + "swapHub": "0xC7BF6Cc3FaAF6c0217DB4ECad3339d7f7d461B7a" +} diff --git a/addresses/euler-addresses-goerli.json b/addresses/euler-addresses-goerli.json index fb42ad9f..64b3be7e 100644 --- a/addresses/euler-addresses-goerli.json +++ b/addresses/euler-addresses-goerli.json @@ -23,10 +23,12 @@ "CRV": "0x87351b560ebc1810CF33cBA7A0b508e2Cf36e821" }, "eulerGeneralView": "0x486492546998494C224b294aE8c5a2982946220B", + "eulerSimpleLens": "0x62626a0f051B547b3182e55D1Eba667138790D8D", "euler": "0x931172BB95549d0f29e10ae2D079ABA3C63318B3", "installer": "0xB21fb96025c2b7F618ba9D3ae955D20Fa303b2D2", "markets": "0x3EbC39b84B1F856fAFE9803A9e1Eae7Da016Da36", "liquidation": "0x66326c072283feE63E1C3feF9BD024F8697EC1BB", "governance": "0x496A8344497875D0D805167874f2f938aEa15600", - "exec": "0x4b62EB6797526491eEf6eF36D3B9960E5d66C394" + "exec": "0x4b62EB6797526491eEf6eF36D3B9960E5d66C394", + "testERC20TokenFaucet": "0x1215396CB53774dCE60978d7237F32042cF3a1db" } diff --git a/addresses/euler-addresses-optimismgoerli.json b/addresses/euler-addresses-optimismgoerli.json new file mode 100644 index 00000000..39c74ef8 --- /dev/null +++ b/addresses/euler-addresses-optimismgoerli.json @@ -0,0 +1,68 @@ +{ + "tokens": { + "EUL": "0x598419fB7cD8829E7471aFe1aFd5c2b35c9A82BC", + "WETH": "0x830e930B18C795192ac20e680bcDd3ce0984B4fB", + "DAI": "0x3189e190202050ae3E54f49bBD79569Ab48FF0dF", + "CRV": "0xc847F5f8de257D48B3c55CB868187381F6B441aA", + "DOUGH": "0x2815C34e27af8Cf632049De1693FbAA0FA10F307", + "REP": "0xfa8FABB91200A381fC74433B3aC3B8A6BF9eA3d0", + "UNI": "0x7FbE772506080fE1261d2Df2d7dA839Ec4Dfac99", + "USDT": "0x3d96928242D0585B45b1218f671875E209081fdd", + "USDC": "0x90E644678b43399659010DD07259ED61E372ddb5", + "WBTC": "0x1231343C8595FC2Da9C16F871e000fa69B68b9b8", + "COMP": "0xCb8Ca7100Cf883769364BAd2324E710E8C17c96f" + }, + "modules": { + "installer": "0xe1DEf83bEF24f9dD5EfdCC79FF21c2a9D3D462B8", + "markets": "0x81E8C68CAD8BDb4F751A3a6cA78f3EC51bDc13d5", + "liquidation": "0xf334f61Eb92F0174AF1e54e0E74A0377050c95b0", + "governance": "0x594a6993bB7A533132D65001a7C99fC66Fae38F4", + "exec": "0xe1c9f61F8934A9Ac2a84a47cde5662b141D5e940", + "swap": "0xeF41850794021D5C95504Ea2b748E6819A79d776", + "swapHub": "0x4aC1d1ba6325F3b0B210De5Ea0e7F8c54A7676B1", + "eToken": "0x98A9728262558BbBbD18921Be51b0Ee0CD7d21B6", + "dToken": "0x0c813db988F760a6df9d6fa93fDe00e8F0d8d742", + "riskManager": "0x43696601BC6dcb54c59aae9E197910e8b5Ff1991", + "irmDefault": "0x93eD364a685c26c55b0Dd8da9baBDf62aF8792C2", + "irmZero": "0x46B5cC46EA4954Def036F8eD261b0Da6eD0E9F35", + "irmFixed": "0x0fdd3Ba574f728A32550334Ed1F09545dE05A8c0", + "irmLinear": "0x18b88C623525909B59BC5f537f03F8f08e9a1823" + }, + "chainlinkCompatOracles": { + "EUL": "0xAF03639AC387a40f77B802C1fcD2363d103eAD56", + "DAI": "0x48bCAd5E4096ceD65aF6994b2B45834A818B0027", + "CRV": "0x313ec45290248bB4E5AD1AB4f5276beEc9224940", + "DOUGH": "0x29B6E822055fD49703e2298CBa55095Bc2CE0856", + "REP": "0xF870dfbe2107ee9C2989B058A30969727AB9924c", + "UNI": "0x62C8b71ce951Cbf020448ad552d1689C9bcfb9a4", + "USDT": "0x6ad40cE1C9D3A518dCE8D89295008ECA1bf0F321", + "USDC": "0xE392Ee380A9917D08B521E9488a66C83364678d2", + "WBTC": "0xe727D925Ab233273d87fAb6Da58446Ed610CEdC7", + "COMP": "0x161a51ff21Bf7dCEb17Be5A4D4F5F1fe8DdEbB33" + }, + "swapHandlers": { + "swapHandlerUniswapV3": "0x61e0F68EcDCb9E7937Ebd2FCAba3f03601500C02", + "swapHandler1Inch": "0x040bEEaC03a1A6BD2E7451Cf05b3f943A947eBFf", + "swapHandlerUniAutoRouter": "0x1d827FD7D55A246BE9975a3fDbba3a56B22Ddf44" + }, + "uniswapV3Factory": "0xdb4B1ccdD88e7e93c2A17bF4e3f270a61189B3E9", + "invariantChecker": "0x83a4bA59679fD4D5a92cB6692b4CDA5E3A1765D6", + "flashLoanNativeTest": "0xeE0CF99D092f46D5c2D4446f4b3A8CC72aDEDc55", + "flashLoanAdaptorTest": "0x324219113D289836554748D24946C962eA4a1b62", + "flashLoanAdaptorTest2": "0x6c53375FcEA59412f406E007F5a212E92B651db4", + "simpleUniswapPeriphery": "0x537E3F6913D9851127f4E26401E3145684f6a433", + "euler": "0xA2a2f0381e7EdE59053ef123d629b228E641677B", + "eulerSimpleLens": "0x251835998B36706e9D2c9A105f2acC4b2Ad73FEa", + "eulerGeneralView": "0x055CF59b5A3dd359b1c75D29C2Cb458c4fb04423", + "installer": "0x3333489a8cDF17AfBDeB20769f27F26A7FD3B1ea", + "markets": "0x307d90808d445cD87Fc3d978853a81d18558B900", + "liquidation": "0xbC6aC233c57e807DA4200f0c3a2D488ddB4633bb", + "governance": "0xC61b87C422Ef31BE093bF717cd14d19886358EEc", + "exec": "0xceA22af69B0689f02aDC192a821E616Fb4f9C160", + "swap": "0xa1Daafd1CD649d6BcfB300722378a3bF6E753B9b", + "swapHub": "0x39E9C04832782aF8291F0CaDbF5B70062c55D7b5", + "flashLoan": "0xbd3a377d413c42ed4e13DE94C2281C6487512178", + "testERC20TokenFaucet": "0x7A9921787a89A49c828667CaA7BBE48010B65D33", + "eulStakes": "0x7B8c159f1d6fC0721a4Ef0C05F22AD4D66700056", + "eulDistributor": "0x66c03CF5a7c7A1eBDda4258B5B78014d28Ab407b" +} diff --git a/addresses/euler-addresses-zktestnet.json b/addresses/euler-addresses-zktestnet.json new file mode 100644 index 00000000..4aff2d08 --- /dev/null +++ b/addresses/euler-addresses-zktestnet.json @@ -0,0 +1,50 @@ +{ + "tokens": { + "EUL": "0x1c4F67DC40ac702c09A9F3963Ac6189D700564E5", + "WETH": "0x3C3881391B8D0a77D4d3849D3Ab81277519716f5", + "DAI": "0x63F52bdcD30c75048E0967F048006EcCf4e4eC0F" + }, + "modules": { + "riskManager": "0xe554593d260F98C195f716c9941Cd92d91E3Ce2B", + "installer": "0x52F6816A5928859E11147B47eD0Dea52e5BaB544", + "markets": "0xc849EF17E59190e135dd4E8effB8bfD97c67D646", + "liquidation": "0xa79751e8c5A275Beb129A932AC42BEca3618feeE", + "governance": "0x72e8f1588C123a498fC3AD56dA5D56Cc7Beb52E8", + "exec": "0x3bC48258E6beB6EAF8f9cD3918487EDA165C54A2", + "swap": "0x1125A7F5DA3B4EBFCA4Ff17aAEA0aF43e63B2162", + "swapHub": "0x225B3acfa0BD7360fF7672ee7260f1CF5842Ab83", + "eToken": "0xeE191Bf568F58a6d912935AFE46bF992e420Ce14", + "dToken": "0x22ea55e1af2C3Ec01b449fcAfcd1633Ed42bBE10", + "irmDefault": "0x60F1a67326cF70edE7b34e9470AB1BC366A738C4", + "irmZero": "0x90A2d723C2c5924d3B535d250A962C97fa5cC8d6", + "irmFixed": "0xc277C48455685e182A82ca35b41b14C006e024b2", + "irmLinear": "0x13aFf878623c85DBd51320517712F80Ce8abb5F0" + }, + "chainlinkCompatOracles": { + "EUL": "0x34B5129e3333d4E3AfEd030F70C3736b6969133B", + "DAI": "0x11e6D43148B1fC3093d439665c2F194282Fb97eF" + }, + "swapHandlers": { + "swapHandlerUniswapV3": "0x7Aec02c571Af43dB0210C5FB84b67dBe1b0c607D", + "swapHandler1Inch": "0x178F033f2110EFaA00bEcA551491D964A8648adE", + "swapHandlerUniAutoRouter": "0x45E938305c30bb3C903Cc39caf4F230c9a8ad8f6" + }, + "invariantChecker": "0x8c2CF4901e0e32C99aC351e5621917c8Db982799", + "flashLoanNativeTest": "0x25e27ecb79c9B9A59c94Ecd2Ff7bD5bE3b9f1613", + "flashLoanAdaptorTest": "0xE4a0E39c6dd8393a0Cc726dbA302C38a25828856", + "flashLoanAdaptorTest2": "0x582f668705C4Ee49E7BcC0B2ECe7772b1ef86360", + "simpleUniswapPeriphery": "0xc87E16a12090750607C92d8E8b0574Eb64Fad44d", + "euler": "0x1DE1a47B6cb8ac33D8A9c6b17654F06BE892e740", + "eulerSimpleLens": "0x1089b0f0f564085C87ac2F953be894102485aAB5", + "eulerGeneralView": "0xD07a02B94495c73D81bF9e9228381b323173d2Eb", + "installer": "0x831Ba37998CBa6F571541eABe033f76c05C1e56E", + "markets": "0x65B6Ee2659939D5Af2794f4825b241D9322Da28d", + "liquidation": "0x62122e664CBcd671Fb2ff91A54CF81d462177151", + "governance": "0x9167bd3A88307391f98a48344196a784f0DcF7d7", + "exec": "0x29Bdb7F0AC23fC3A624917c70F0A633966D45552", + "swap": "0xF19C40a9d8D8D6ebEfE8974DFae3F89fEB3F823a", + "swapHub": "0x07f120683e611123d2Ab25be8C3DE9681A5e0c79", + "flashLoan": "0x9E5E5fB41B1f44eD7391F86Fd5Cc1a6ea9611D58", + "eulStakes": "0x12B8442C15093E3a33dBF13309085532217B7B70", + "eulDistributor": "0xb224c67b2Ea6c127AC24156C9C70e4fe2709294b" +} diff --git a/contracts/Constants.sol b/contracts/Constants.sol index 0a524352..dcd2ba8b 100644 --- a/contracts/Constants.sol +++ b/contracts/Constants.sol @@ -37,9 +37,13 @@ abstract contract Constants { uint8 internal constant DEFERLIQUIDITY__CLEAN = 1; uint8 internal constant DEFERLIQUIDITY__DIRTY = 2; + // Fiat currency Reference Assets, as per ISO 4217 + // https://en.wikipedia.org/wiki/ISO_4217 + address internal constant REFERENCE_ASSET__USD = address(840); // Pricing types + uint16 internal constant PRICINGTYPE__INVALID = 0; uint16 internal constant PRICINGTYPE__PEGGED = 1; uint16 internal constant PRICINGTYPE__UNISWAP3_TWAP = 2; uint16 internal constant PRICINGTYPE__FORWARDED = 3; diff --git a/contracts/lib/UniswapV3Lib.sol b/contracts/lib/UniswapV3Lib.sol new file mode 100644 index 00000000..24fa145e --- /dev/null +++ b/contracts/lib/UniswapV3Lib.sol @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import "../vendor/TickMath.sol"; +import "../vendor/FullMath.sol"; + +interface IUniswapV3Factory { + function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool); +} + +interface IUniswapV3Pool { + function slot0() external view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked); + function liquidity() external view returns (uint128); + function observe(uint32[] calldata secondsAgos) external view returns (int56[] memory tickCumulatives, uint160[] memory liquidityCumulatives); + function observations(uint256 index) external view returns (uint32 blockTimestamp, int56 tickCumulative, uint160 liquidityCumulative, bool initialized); + function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external; +} + +library UniswapV3Lib { + function findBestUniswapPool(address factory, address underlying, address referenceAsset) internal view returns (address pool, uint24 fee) { + pool = address(0); + fee = 0; + + uint24[4] memory fees = [uint24(3000), 10000, 500, 100]; + uint128 bestLiquidity = 0; + + for (uint i = 0; i < fees.length; ++i) { + address candidatePool = IUniswapV3Factory(factory).getPool(underlying, referenceAsset, fees[i]); + if (candidatePool == address(0)) continue; + + uint128 liquidity = IUniswapV3Pool(candidatePool).liquidity(); + + if (pool == address(0) || liquidity > bestLiquidity) { + pool = candidatePool; + fee = fees[i]; + bestLiquidity = liquidity; + } + } + } + + function computeUniswapPoolAddress(address factory, bytes32 poolInitCodeHash, address tokenA, address tokenB, uint24 fee) internal pure returns (address) { + if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); + + return address(uint160(uint256(keccak256(abi.encodePacked( + hex'ff', + factory, + keccak256(abi.encode(tokenA, tokenB, fee)), + poolInitCodeHash + ))))); + } + + function uniswapObserve(address pool, uint ago) internal view returns (uint, uint) { + uint32[] memory secondsAgos = new uint32[](2); + + secondsAgos[0] = uint32(ago); + secondsAgos[1] = 0; + + (bool success, bytes memory data) = pool.staticcall(abi.encodeWithSelector(IUniswapV3Pool.observe.selector, secondsAgos)); + + if (!success) { + if (keccak256(data) != keccak256(abi.encodeWithSignature("Error(string)", "OLD"))) revertBytes(data); + + // The oldest available observation in the ring buffer is the index following the current (accounting for wrapping), + // since this is the one that will be overwritten next. + + (,, uint16 index, uint16 cardinality,,,) = IUniswapV3Pool(pool).slot0(); + + (uint32 oldestAvailableAge,,,bool initialized) = IUniswapV3Pool(pool).observations((index + 1) % cardinality); + + // If the following observation in a ring buffer of our current cardinality is uninitialized, then all the + // observations at higher indices are also uninitialized, so we wrap back to index 0, which we now know + // to be the oldest available observation. + + if (!initialized) (oldestAvailableAge,,,) = IUniswapV3Pool(pool).observations(0); + + // Call observe() again to get the oldest available + + ago = block.timestamp - oldestAvailableAge; + secondsAgos[0] = uint32(ago); + + (success, data) = pool.staticcall(abi.encodeWithSelector(IUniswapV3Pool.observe.selector, secondsAgos)); + if (!success) revertBytes(data); + } + + // If uniswap pool doesn't exist, then data will be empty and this decode will throw: + + int56[] memory tickCumulatives = abi.decode(data, (int56[])); // don't bother decoding the liquidityCumulatives array + + int24 tick = int24((tickCumulatives[1] - tickCumulatives[0]) / int56(int(ago))); + + return (TickMath.getSqrtRatioAtTick(tick), ago); + } + + function revertBytes(bytes memory errMsg) internal pure { + if (errMsg.length > 0) { + assembly { + revert(add(32, errMsg), mload(errMsg)) + } + } + + revert("e/uniswap-v3-twap-empty-error"); + } +} diff --git a/contracts/modules/Exec.sol b/contracts/modules/Exec.sol index dbc3a40e..679ab37d 100644 --- a/contracts/modules/Exec.sol +++ b/contracts/modules/Exec.sol @@ -117,6 +117,29 @@ contract Exec is BaseLogic { revert("e/batch/simulation-did-not-revert"); } + /// @notice Call batch dispatch and catch the revert and parse it to EulerBatchItemResponse[] + /// @param items List of operations to execute + /// @param deferLiquidityChecks List of user accounts to defer liquidity checks for + /// @dev During simulation all batch items are executed, regardless of the `allowError` flag + function batchDispatchSimulateDecoded(EulerBatchItem[] calldata items, address[] calldata deferLiquidityChecks) external reentrantOK returns (EulerBatchItemResponse[] memory simulation) { + address msgSender = unpackTrailingParamMsgSender(); + bytes memory data = abi.encodeWithSelector(Exec.batchDispatchSimulate.selector, items, deferLiquidityChecks); + bytes memory inputWrapped = abi.encodePacked(data, uint160(msgSender), uint160(msg.sender)); // msg.sender is the proxy address + (, bytes memory reason) = moduleLookup[MODULEID__EXEC].delegatecall(inputWrapped); + + bytes4 errorSelector = bytes4(reason); + if(errorSelector != BatchDispatchSimulation.selector){ + revertBytes(reason); + } + assembly { + reason := add(reason, 0x4) + } + simulation = abi.decode( + reason, + (EulerBatchItemResponse[]) + ); + } + // Average liquidity tracking diff --git a/contracts/modules/Markets.sol b/contracts/modules/Markets.sol index b0bd366c..42b2d48a 100644 --- a/contracts/modules/Markets.sol +++ b/contracts/modules/Markets.sol @@ -11,6 +11,13 @@ import "../PToken.sol"; contract Markets is BaseLogic { constructor(bytes32 moduleGitCommit_) BaseLogic(MODULEID__MARKETS, moduleGitCommit_) {} + modifier governorOnly { + address msgSender = unpackTrailingParamMsgSender(); + + require(msgSender == governorAdmin, "e/markets/unauthorized"); + _; + } + /// @notice Create an Euler pool and associated EToken and DToken addresses. /// @param underlying The address of an ERC20-compliant token. There must be an initialised uniswap3 pool for the underlying/reference asset pair. /// @return The created EToken, or the existing EToken if already activated. @@ -19,6 +26,17 @@ contract Markets is BaseLogic { return doActivateMarket(underlying); } + function activateMarketWithChainlinkPriceFeed(address underlying, address chainlinkAggregator) external nonReentrant governorOnly returns (address) { + require(pTokenLookup[underlying] == address(0), "e/markets/invalid-token"); + require(underlyingLookup[underlying].eTokenAddress == address(0), "e/market/underlying-already-activated"); + require(chainlinkAggregator != address(0), "e/markets/bad-chainlink-address"); + + chainlinkPriceFeedLookup[underlying] = chainlinkAggregator; + emit GovSetChainlinkPriceFeed(underlying, chainlinkAggregator); + + return doActivateMarket(underlying); + } + function doActivateMarket(address underlying) private returns (address) { // Pre-existing @@ -43,6 +61,11 @@ contract Markets is BaseLogic { (params) = abi.decode(result, (IRiskManager.NewMarketParameters)); } + if (chainlinkPriceFeedLookup[underlying] != address(0)) { + params.pricingType = PRICINGTYPE__CHAINLINK; + } + + require(params.pricingType != PRICINGTYPE__INVALID, "e/markets/pricing-type-invalid"); // Create proxies diff --git a/contracts/modules/RiskManager.sol b/contracts/modules/RiskManager.sol index 7b5a1dd9..a431c058 100644 --- a/contracts/modules/RiskManager.sol +++ b/contracts/modules/RiskManager.sol @@ -4,23 +4,9 @@ pragma solidity ^0.8.0; import "../BaseLogic.sol"; import "../IRiskManager.sol"; -import "../vendor/TickMath.sol"; -import "../vendor/FullMath.sol"; +import "../lib/UniswapV3Lib.sol"; - -interface IUniswapV3Factory { - function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool); -} - -interface IUniswapV3Pool { - function slot0() external view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked); - function liquidity() external view returns (uint128); - function observe(uint32[] calldata secondsAgos) external view returns (int56[] memory tickCumulatives, uint160[] memory liquidityCumulatives); - function observations(uint256 index) external view returns (uint32 blockTimestamp, int56 tickCumulative, uint160 liquidityCumulative, bool initialized); - function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external; -} - interface IChainlinkAggregatorV2V3 { function latestAnswer() external view returns (int256); } @@ -48,6 +34,8 @@ contract RiskManager is IRiskManager, BaseLogic { // Default market parameters function getNewMarketParameters(address underlying) external override returns (NewMarketParameters memory p) { + p.pricingType = PRICINGTYPE__INVALID; + p.pricingParameters = uint32(0); p.config.borrowIsolated = true; p.config.collateralFactor = uint32(0); p.config.borrowFactor = type(uint32).max; @@ -63,7 +51,7 @@ contract RiskManager is IRiskManager, BaseLogic { p.pricingParameters = uint32(0); p.config.collateralFactor = underlyingLookup[pTokenLookup[underlying]].collateralFactor; - } else { + } else if (uniswapFactory != address(0)) { // Uniswap3 TWAP // The uniswap pool (fee-level) with the highest in-range liquidity is used by default. @@ -71,41 +59,22 @@ contract RiskManager is IRiskManager, BaseLogic { // verify the selection is suitable before using the pool. Otherwise, governance will // need to change the pricing config for the market. - address pool = address(0); - uint24 fee = 0; - - { - uint24[4] memory fees = [uint24(3000), 10000, 500, 100]; - uint128 bestLiquidity = 0; - - for (uint i = 0; i < fees.length; ++i) { - address candidatePool = IUniswapV3Factory(uniswapFactory).getPool(underlying, referenceAsset, fees[i]); - if (candidatePool == address(0)) continue; + (address pool, uint24 fee) = UniswapV3Lib.findBestUniswapPool(uniswapFactory, underlying, referenceAsset); + if (pool != address(0)) { + require(UniswapV3Lib.computeUniswapPoolAddress(uniswapFactory, uniswapPoolInitCodeHash, underlying, referenceAsset, fee) == pool, "e/bad-uniswap-pool-addr"); - uint128 liquidity = IUniswapV3Pool(candidatePool).liquidity(); + p.pricingType = PRICINGTYPE__UNISWAP3_TWAP; + p.pricingParameters = uint32(fee); - if (pool == address(0) || liquidity > bestLiquidity) { - pool = candidatePool; - fee = fees[i]; - bestLiquidity = liquidity; - } + try IUniswapV3Pool(pool).increaseObservationCardinalityNext(MIN_UNISWAP3_OBSERVATION_CARDINALITY) { + // Success + } catch Error(string memory err) { + if (keccak256(bytes(err)) == keccak256("LOK")) revert("e/risk/uniswap-pool-not-inited"); + revert(string(abi.encodePacked("e/risk/uniswap/", err))); + } catch (bytes memory returnData) { + revertBytes(returnData); } } - - require(pool != address(0), "e/no-uniswap-pool-avail"); - require(computeUniswapPoolAddress(underlying, fee) == pool, "e/bad-uniswap-pool-addr"); - - p.pricingType = PRICINGTYPE__UNISWAP3_TWAP; - p.pricingParameters = uint32(fee); - - try IUniswapV3Pool(pool).increaseObservationCardinalityNext(MIN_UNISWAP3_OBSERVATION_CARDINALITY) { - // Success - } catch Error(string memory err) { - if (keccak256(bytes(err)) == keccak256("LOK")) revert("e/risk/uniswap-pool-not-inited"); - revert(string(abi.encodePacked("e/risk/uniswap/", err))); - } catch (bytes memory returnData) { - revertBytes(returnData); - } } } @@ -113,20 +82,6 @@ contract RiskManager is IRiskManager, BaseLogic { // Pricing - function computeUniswapPoolAddress(address underlying, uint24 fee) private view returns (address) { - address tokenA = underlying; - address tokenB = referenceAsset; - if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); - - return address(uint160(uint256(keccak256(abi.encodePacked( - hex'ff', - uniswapFactory, - keccak256(abi.encode(tokenA, tokenB, fee)), - uniswapPoolInitCodeHash - ))))); - } - - function decodeSqrtPriceX96(address underlying, uint underlyingDecimalsScaler, uint sqrtPriceX96) private view returns (uint price) { if (uint160(underlying) < uint160(referenceAsset)) { price = FullMath.mulDiv(sqrtPriceX96, sqrtPriceX96, uint(2**(96*2)) / 1e18) / underlyingDecimalsScaler; @@ -140,46 +95,9 @@ contract RiskManager is IRiskManager, BaseLogic { else if (price == 0) price = 1; } - function callUniswapObserve(address underlying, uint underlyingDecimalsScaler, address pool, uint ago) private view returns (uint, uint) { - uint32[] memory secondsAgos = new uint32[](2); - - secondsAgos[0] = uint32(ago); - secondsAgos[1] = 0; - - (bool success, bytes memory data) = pool.staticcall(abi.encodeWithSelector(IUniswapV3Pool.observe.selector, secondsAgos)); - - if (!success) { - if (keccak256(data) != keccak256(abi.encodeWithSignature("Error(string)", "OLD"))) revertBytes(data); - - // The oldest available observation in the ring buffer is the index following the current (accounting for wrapping), - // since this is the one that will be overwritten next. - - (,, uint16 index, uint16 cardinality,,,) = IUniswapV3Pool(pool).slot0(); - - (uint32 oldestAvailableAge,,,bool initialized) = IUniswapV3Pool(pool).observations((index + 1) % cardinality); - - // If the following observation in a ring buffer of our current cardinality is uninitialized, then all the - // observations at higher indices are also uninitialized, so we wrap back to index 0, which we now know - // to be the oldest available observation. - - if (!initialized) (oldestAvailableAge,,,) = IUniswapV3Pool(pool).observations(0); - - // Call observe() again to get the oldest available - - ago = block.timestamp - oldestAvailableAge; - secondsAgos[0] = uint32(ago); - - (success, data) = pool.staticcall(abi.encodeWithSelector(IUniswapV3Pool.observe.selector, secondsAgos)); - if (!success) revertBytes(data); - } - - // If uniswap pool doesn't exist, then data will be empty and this decode will throw: - - int56[] memory tickCumulatives = abi.decode(data, (int56[])); // don't bother decoding the liquidityCumulatives array - - int24 tick = int24((tickCumulatives[1] - tickCumulatives[0]) / int56(int(ago))); - - uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(tick); + function callUniswapObserve(address underlying, uint pricingParameters, uint twapWindow, uint underlyingDecimalsScaler) private view returns (uint, uint) { + address pool = UniswapV3Lib.computeUniswapPoolAddress(uniswapFactory, uniswapPoolInitCodeHash, underlying, referenceAsset, uint24(pricingParameters)); + (uint sqrtPriceX96, uint ago) = UniswapV3Lib.uniswapObserve(pool, twapWindow); return (decodeSqrtPriceX96(underlying, underlyingDecimalsScaler, sqrtPriceX96), ago); } @@ -201,6 +119,11 @@ contract RiskManager is IRiskManager, BaseLogic { } price = uint(answer); + + // if reference asset is USD, it implies that Chainlink asset/USD price feeds are used. + // Chainlink asset/USD price feeds are 8 decimals, so we need to scale them up to 18 decimals + if (referenceAsset == REFERENCE_ASSET__USD) price = price * 1e10; + if (price > 1e36) price = 1e36; } @@ -233,22 +156,22 @@ contract RiskManager is IRiskManager, BaseLogic { twap = 1e18; twapPeriod = twapWindow; } else if (pricingType == PRICINGTYPE__UNISWAP3_TWAP) { - address pool = computeUniswapPoolAddress(underlying, uint24(pricingParameters)); - (twap, twapPeriod) = callUniswapObserve(underlying, underlyingDecimalsScaler, pool, twapWindow); + if (uniswapFactory != address(0)) { + (twap, twapPeriod) = callUniswapObserve(underlying, pricingParameters, twapWindow, underlyingDecimalsScaler); + } } else if (pricingType == PRICINGTYPE__CHAINLINK) { twap = callChainlinkLatestAnswer(chainlinkPriceFeedLookup[underlying]); twapPeriod = 0; // if price invalid and uniswap fallback pool configured get the price from uniswap - if (twap == 0 && uint24(pricingParameters) != 0) { - address pool = computeUniswapPoolAddress(underlying, uint24(pricingParameters)); - (twap, twapPeriod) = callUniswapObserve(underlying, underlyingDecimalsScaler, pool, twapWindow); + if (twap == 0 && uint24(pricingParameters) != 0 && uniswapFactory != address(0)) { + (twap, twapPeriod) = callUniswapObserve(underlying, pricingParameters, twapWindow, underlyingDecimalsScaler); } - - require(twap != 0, "e/unable-to-get-the-price"); } else { revert("e/unknown-pricing-type"); } + + require(twap != 0, "e/unable-to-get-the-price"); } function getPrice(address underlying) external view override returns (uint twap, uint twapPeriod) { @@ -273,8 +196,8 @@ contract RiskManager is IRiskManager, BaseLogic { if (pricingType == PRICINGTYPE__PEGGED) { currPrice = 1e18; - } else if (pricingType == PRICINGTYPE__UNISWAP3_TWAP || pricingType == PRICINGTYPE__FORWARDED) { - address pool = computeUniswapPoolAddress(newUnderlying, uint24(pricingParameters)); + } else if (pricingType == PRICINGTYPE__UNISWAP3_TWAP) { + address pool = UniswapV3Lib.computeUniswapPoolAddress(uniswapFactory, uniswapPoolInitCodeHash, underlying, referenceAsset, uint24(pricingParameters)); (uint160 sqrtPriceX96,,,,,,) = IUniswapV3Pool(pool).slot0(); currPrice = decodeSqrtPriceX96(newUnderlying, underlyingDecimalsScaler, sqrtPriceX96); } else if (pricingType == PRICINGTYPE__CHAINLINK) { diff --git a/contracts/test/MockEACAggregatorProxy.sol b/contracts/test/MockEACAggregatorProxy.sol index c75effd7..fb7100b8 100644 --- a/contracts/test/MockEACAggregatorProxy.sol +++ b/contracts/test/MockEACAggregatorProxy.sol @@ -10,6 +10,7 @@ contract MockAggregatorProxy { uint80 answeredInRound; // The round ID of the round in which the answer was computed. } + address public owner; string constant description_ = "Mock Aggregator"; uint256 constant version_ = 1; uint8 public decimals_; @@ -18,14 +19,24 @@ contract MockAggregatorProxy { constructor(uint8 _decimals) { decimals_ = _decimals; + owner = msg.sender; } - function mockSetData(Data calldata data) external { + modifier onlyOwner() { + require(msg.sender == owner, "unauthorized"); + _; + } + + function changeOwner(address newOwner) external onlyOwner { + owner = newOwner; + } + + function mockSetData(Data calldata data) external onlyOwner { data_[data.roundId] = data; currentRoundId_ = data.roundId; } - function mockSetValidAnswer(int256 answer) external { + function mockSetValidAnswer(int256 answer) external onlyOwner { currentRoundId_++; data_[currentRoundId_] = Data( diff --git a/contracts/test/TestERC20TokenFaucet.sol b/contracts/test/TestERC20TokenFaucet.sol new file mode 100644 index 00000000..b638392b --- /dev/null +++ b/contracts/test/TestERC20TokenFaucet.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +interface IERC20 { + function transfer(address recipient, uint256 amount) external returns (bool); + function decimals() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); +} + +contract TestERC20TokenFaucet { + address public owner; + mapping(address => uint256) thresholds; + + constructor() { + owner = msg.sender; + } + + function withdraw(address underlying) external { + uint256 balance = IERC20(underlying).balanceOf(msg.sender); + uint256 amount = getThreshold(underlying); + require(balance < amount, "withdraw: balance not below threshold"); + IERC20(underlying).transfer(msg.sender, amount - balance); + } + + function getThreshold(address underlying) public view returns(uint256) { + return thresholds[underlying]; + } + + // Owner functions + + modifier onlyOwner { + require(msg.sender == owner, "unauthorized"); + _; + } + + function setThreshold(address underlying, uint256 _threshold) external onlyOwner { + require(_threshold > 0, "setThreshold: threshold must be greater than zero"); + thresholds[underlying] = _threshold; + } + + function reduceFaucetBalance(address underlying, uint256 amount) external onlyOwner { + if (amount == type(uint256).max) { + uint balance = IERC20(underlying).balanceOf(address(this)); + IERC20(underlying).transfer(msg.sender, balance); + } else { + IERC20(underlying).transfer(msg.sender, amount); + } + } +} diff --git a/contracts/views/DeltaBalances.sol b/contracts/views/DeltaBalances.sol new file mode 100644 index 00000000..8204ccce --- /dev/null +++ b/contracts/views/DeltaBalances.sol @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + + +// source: https://etherscan.io/address/0xbf320b8336b131e0270295c15478d91741f9fc11#code +/* + Contract for DeltaBalances.github.io V5. + Check values for multiple ERC20 tokens in a single request + - token balances + - token allowances + - deposited token balances (decentralized exchanges) + + V5 changes: + - Update to Solidity 0.5 (breaking changes) + - Add support for alternative balance functions using function selectors + + + Address 0x0 is used to resemble ETH as a token (as used in EtherDelta, IDEX and more). + + + To call the new 'generic' functions, this contract uses function selectors based on the hash of function signatures (see getFunctionSelector). + + Some useful function signatures (bytes4): + + SIGNATURE SELECTOR FUNCTION CONTRACTS + ---------------------------------------------------------------------------------------------------------------------------- + "balanceOf(address)" 0x70a08231 balanceOf(user) (ERC20, ERC223, ERC777 and more) + "allowance(address,address)" 0xdd62ed3e allowance(owner, spender) (ERC20 tokens) + + "balanceOf(address,address)" 0xf7888aec balanceOf(token, user) (EtherDelta, IDEX, Token Store, R1 protocol, and more) + "getBalance(address,address)" 0xd4fac45d getBalance(token, user) (JOYSO) + "balances(address,address)" 0xc23f001f balances(user, token) (Switcheo) + "balances(address)" 0x27e235e3 balances(user) (ETHEN ETH) + "tokens(address,address)" 0x508493bc tokens(user, tokens) (ETHEN tokens) + + + + Preious version (V4) -> 0x40a38911e470fc088beeb1a9480c2d69c847bcec +*/ + +// ERC20 contract interface for token transfers. +abstract contract Token { + function transfer(address to, uint256 tokens) + public + virtual + returns (bool success); +} + +// Exchange contract Interface for EtherDelta and forks. +abstract contract Exchange { + function balanceOf(address token, address user) + public + view + virtual + returns (uint256); +} + +contract DeltaBalances { + address payable public admin; + + constructor() { + admin = payable(msg.sender); + } + + /* admin functionality */ + + // Limit withdrawals to the contract creator. + modifier isAdmin() { + require(msg.sender == admin); + _; + } + + // Backup withdraw, in case ETH gets in here. + function withdraw() external isAdmin { + admin.transfer(address(this).balance); + } + + // Backup withdraw, in case ERC20 tokens get in here. + function withdrawToken(address token, uint256 amount) external isAdmin { + require( + token != address(0x0) && Token(token).transfer(msg.sender, amount) + ); + } + + /* public functions */ + + /* Get the function selector from a function signature. + functionSignature: + - remove whitespace and variable names. + use "balanceOf(address,address)" NOT "balanceOf(address token, address user)" + + See the top comment for common selectors. + */ + function getFunctionSelector(string calldata functionSignature) + external + pure + returns (bytes4) + { + // calculate the keccak256 hash of the function signature and return a 4 bytes value + return bytes4(keccak256(abi.encodePacked(functionSignature))); + } + + /* Check the ERC20 token balances of a wallet for multiple tokens. + Returns array of token balances in wei units. */ + function tokenBalances(address user, address[] calldata tokens) + external + view + returns (uint256[] memory balances) + { + balances = new uint256[](tokens.length); + + for (uint256 i = 0; i < tokens.length; i++) { + if (tokens[i] != address(0x0)) { + balances[i] = tokenBalance(user, tokens[i]); // check token balance and catch errors + } else { + balances[i] = user.balance; // ETH balance + } + } + return balances; + } + + /* Check the token allowances of a specific contract for multiple tokens. + Returns array of deposited token balances in wei units. */ + function tokenAllowances( + address spenderContract, + address user, + address[] calldata tokens + ) external view returns (uint256[] memory allowances) { + allowances = new uint256[](tokens.length); + + for (uint256 i = 0; i < tokens.length; i++) { + allowances[i] = tokenAllowance(spenderContract, user, tokens[i]); // check token allowance and catch errors + } + return allowances; + } + + /* Get multiple token balances deposited on a DEX using the traditional balanceOf function (EtherDelta, IDEX, Token Store, R1 protocol and many more). + Returns array of deposited token balances in wei units. + + This doesn't use the generic version (below) as this format is the most common and it is more efficient hardcoded + */ + function depositedBalances( + address exchange, + address user, + address[] calldata tokens + ) external view returns (uint256[] memory balances) { + balances = new uint256[](tokens.length); + Exchange ex = Exchange(exchange); + + for (uint256 i = 0; i < tokens.length; i++) { + balances[i] = ex.balanceOf(tokens[i], user); //Errors if exchange does not implement 'balanceOf' correctly, use depositedBalancesGeneric instead. + } + return balances; + } + + /* Get multiple token balances deposited on a DEX with a function selector + - Selector: hashed function signature, see 'getFunctionSelector' + - userFist: determines whether the function uses foo(user, token) or foo(token, user) + Returns array of deposited token balances in wei units. */ + function depositedBalancesGeneric( + address exchange, + bytes4 selector, + address user, + address[] calldata tokens, + bool userFirst + ) external view returns (uint256[] memory balances) { + balances = new uint256[](tokens.length); + + if (userFirst) { + for (uint256 i = 0; i < tokens.length; i++) { + balances[i] = getNumberTwoArgs( + exchange, + selector, + user, + tokens[i] + ); + } + } else { + for (uint256 i = 0; i < tokens.length; i++) { + balances[i] = getNumberTwoArgs( + exchange, + selector, + tokens[i], + user + ); + } + } + return balances; + } + + /* Get the deposited ETH balance for a DEX that uses a separate function for ETH balance instead of token 0x0. + - Selector: hashed function signature, see 'getFunctionSelector' + Returns deposited balance in wei units. */ + function depositedEtherGeneric( + address exchange, + bytes4 selector, + address user + ) external view returns (uint256) { + return getNumberOneArg(exchange, selector, user); + } + + /* Private functions */ + + /* Check the token balance of a wallet in a token contract. + Returns 0 on a bad token contract */ + function tokenBalance(address user, address token) + internal + view + returns (uint256) + { + // token.balanceOf(user), selector 0x70a08231 + return getNumberOneArg(token, 0x70a08231, user); + } + + /* Check the token allowance of a wallet for a specific contract. + Returns 0 on a bad token contract. */ + function tokenAllowance( + address spenderContract, + address user, + address token + ) internal view returns (uint256) { + // token.allowance(owner, spender), selector 0xdd62ed3e + return getNumberTwoArgs(token, 0xdd62ed3e, user, spenderContract); + } + + /* Generic private functions */ + + // Get a token or exchange value that requires 1 address argument (most likely arg1 == user). + // selector is the hashed function signature (see top comments) + function getNumberOneArg( + address contractAddr, + bytes4 selector, + address arg1 + ) internal view returns (uint256) { + if (isAContract(contractAddr)) { + (bool success, bytes memory result) = contractAddr.staticcall( + abi.encodeWithSelector(selector, arg1) + ); + // if the contract call succeeded & the result looks good to parse + if (success && result.length == 32) { + return abi.decode(result, (uint256)); // return the result as uint + } else { + return 0; // function call failed, return 0 + } + } else { + return 0; // not a valid contract, return 0 instead of error + } + } + + // Get an exchange balance requires 2 address arguments ( (token, user) and (user, token) are both common). + // selector is the hashed function signature (see top comments) + function getNumberTwoArgs( + address contractAddr, + bytes4 selector, + address arg1, + address arg2 + ) internal view returns (uint256) { + if (isAContract(contractAddr)) { + (bool success, bytes memory result) = contractAddr.staticcall( + abi.encodeWithSelector(selector, arg1, arg2) + ); + // if the contract call succeeded & the result looks good to parse + if (success && result.length == 32) { + return abi.decode(result, (uint256)); // return the result as uint + } else { + return 0; // function call failed, return 0 + } + } else { + return 0; // not a valid contract, return 0 instead of error + } + } + + // check if contract (token, exchange) is actually a smart contract and not a 'regular' address + function isAContract(address contractAddr) internal view returns (bool) { + uint256 codeSize; + assembly { + codeSize := extcodesize(contractAddr) + } // contract code size + return codeSize > 0; + // Might not be 100% foolproof, but reliable enough for an early return in 'view' functions + } +} diff --git a/docs/contract_deployment.md b/docs/contract_deployment.md new file mode 100644 index 00000000..fc3ec21e --- /dev/null +++ b/docs/contract_deployment.md @@ -0,0 +1,52 @@ +# Smart contract deployments and verification + +// hardhat testing - NETWORK_NAME=testing-chainlink-no-uni-deploy npx hardhat run scripts/prod-setup.js --network hardhat +// testing binance testnet - VERIFY_CONTRACTS=true NETWORK_NAME=testing-chainlink-no-uni-deploy npx hardhat run scripts/prod-setup.js --network bsctestnet + +This document provides a guide for the deployment and verification of the smart contracts. + + +## Smart contract deployment + +module.exports = { + riskManagerSettings: {}, + + testing: { + tokens: [], + uniswapPools: [], + activated: [], + chainlinkPrices: {}, + chainlinkOracles: [], + }, +} + +deploys contracts + +spits out two files for evm and zkSync +addresses file +constructor arguments file for hardhat verification and in the case of zkSync for verification on their explorer as well. + +populate the price oracle property if .... + +copy addresses file to addresses directory (and rename network name if input file has different name) +add token addresses to token setups named after network name in hardhat and env + + +## Smart contract verification + +add flag +hardhat verification is supported on the following networks in deploy-lib: +* +* +* + +ensure env variable is set with correct api key for the chain explorer, e.g., etherscan, bscscan, polygonscan +this will do automatic verification using this command from hardhat docs +https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-etherscan + + +output file for verification has the path to the smart contract and constructor arguments + +or user can do manual verification for any that fails + +there is also hardhat task that can be used for verification \ No newline at end of file diff --git a/hardhat.config.js b/hardhat.config.js index 5a4c90e4..49479efa 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -19,6 +19,12 @@ for (let file of files) { // Config module.exports = { + // zksync config + zksolc: { + version: "1.3.1", + compilerSource: "binary", + settings: {}, + }, networks: { hardhat: { hardfork: 'arrowGlacier', @@ -60,9 +66,17 @@ module.exports = { //runOnCompile: true, }, + etherscan: { + apiKey: {}, + }, + mocha: { timeout: 100000 - } + }, + + etherscan: { + apiKey: {}, + }, }; @@ -85,25 +99,45 @@ for (let k in process.env) { accounts: [`0x${process.env.PRIVATE_KEY}`], } } + + if (networkName === "zktestnet" && process.env.RPC_URL_GOERLI) { + // zksync config + require("@matterlabs/hardhat-zksync-deploy"); + require("@matterlabs/hardhat-zksync-solc"); + + module.exports.networks = { + ...module.exports.networks, + [networkName]: { + url: `${process.env[k]}`, + ethNetwork: `${process.env.RPC_URL_GOERLI}`, + zksync: true, + } + } + + module.exports.zkSyncDeploy = { + zkSyncNetwork: `${process.env[k]}`, + ethNetwork: `${process.env.RPC_URL_GOERLI}` + } + } } if (k === "ETHERSCAN_API_KEY") { - module.exports.etherscan = { - apiKey: { - // ethereum smart contract verification key - mainnet: process.env[k], - goerli: process.env[k] - } - } + module.exports.etherscan.apiKey.mainnet = process.env[k]; + module.exports.etherscan.apiKey.goerli = process.env[k]; } if (k === "POLYGONSCAN_API_KEY") { - module.exports.etherscan = { - apiKey: { - // polygon smart contract verification key - polygon: process.env[k], - polygonMumbai: process.env[k] - } - } + module.exports.etherscan.apiKey.polygon = process.env[k]; + module.exports.etherscan.apiKey.polygonMumbai = process.env[k]; + } + + if (k === "BSCSCAN_API_KEY") { + module.exports.etherscan.apiKey.bsc = process.env[k]; + module.exports.etherscan.apiKey.bscTestnet = process.env[k]; + } + + if (k === "OPTIMISMSCAN_API_KEY") { + module.exports.etherscan.apiKey.optimisticEthereum = process.env[k]; + module.exports.etherscan.apiKey.optimisticGoerli = process.env[k]; } } diff --git a/package-lock.json b/package-lock.json index b8d6c85e..0ae94074 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,28 +9,42 @@ "version": "1.0.0", "license": "UNLICENSED", "dependencies": { + "@matterlabs/hardhat-zksync-verify": "^0.1.1", "dotenv": "^8.2.0", "hardhat-spdx-license-identifier": "^2.0.3", "seedrandom": "^3.0.5" }, "devDependencies": { + "@ethersproject/hash": "^5.7.0", + "@ethersproject/web": "^5.7.1", + "@matterlabs/hardhat-zksync-deploy": "^0.6.1", + "@matterlabs/hardhat-zksync-solc": "^0.3.14", "@nomiclabs/hardhat-ethers": "^2.0.0", "@nomiclabs/hardhat-etherscan": "^3.1.2", "@nomiclabs/hardhat-waffle": "^2.0.0", + "@types/node": "^18.13.0", "@uniswap/sdk-core": "^3.0.1", "@uniswap/v3-sdk": "^3.4.1", "chai": "^4.2.0", "cross-fetch": "^3.1.4", "ethereum-block-by-date": "^1.4.2", "ethereum-waffle": "^3.3.0", - "ethers": "^5.7.0", + "ethers": "^5.7.2", "ganache-cli": "^6.12.1", - "hardhat": "^2.10.2", + "hardhat": "^2.12.7", "hardhat-contract-sizer": "^2.0.3", "hardhat-gas-reporter": "^1.0.6", - "solidity-coverage": "^0.7.16" + "solidity-coverage": "^0.7.16", + "ts-node": "^10.9.1", + "typescript": "^4.9.5", + "zksync-web3": "^0.13.1" } }, + "node_modules/@balena/dockerignore": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", + "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -41,6 +55,18 @@ "node": ">=0.1.90" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@ensdomains/ens": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", @@ -743,9 +769,9 @@ } }, "node_modules/@ethersproject/providers": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.1.tgz", - "integrity": "sha512-vZveG/DLyo+wk4Ga1yx6jSEHrLPgmTt+dFv0dv8URpVCRf0jVhalps1jq/emN/oXnMRsC7cQgAF32DcXLL7BPQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", "dev": true, "funding": [ { @@ -1032,6 +1058,224 @@ "@ethersproject/strings": "^5.7.0" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "devOptional": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "devOptional": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@matterlabs/hardhat-zksync-deploy": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@matterlabs/hardhat-zksync-deploy/-/hardhat-zksync-deploy-0.6.1.tgz", + "integrity": "sha512-5uVcJGAc5cjWB1GjrUC/XAmF/03+QhoCaZiZA6HplgTJ9bzSWZ+Zzr+B18TFUD8+4fL8iBdstVlhw3C4j0/QLg==", + "dev": true, + "dependencies": { + "chalk": "4.1.2" + }, + "peerDependencies": { + "ethers": "~5.7.2", + "hardhat": "^2.12.4", + "zksync-web3": "^0.12.3" + } + }, + "node_modules/@matterlabs/hardhat-zksync-deploy/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@matterlabs/hardhat-zksync-deploy/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@matterlabs/hardhat-zksync-deploy/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@matterlabs/hardhat-zksync-deploy/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@matterlabs/hardhat-zksync-deploy/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@matterlabs/hardhat-zksync-deploy/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@matterlabs/hardhat-zksync-solc": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.3.14.tgz", + "integrity": "sha512-iKuQ+vvnpv3K2lkFO41xpJcNWH0KHJ/5JbOboTlPZATVR7F3GJeHfJL+GG4wkxKXnxZczpxyQqC4rAfMKvRaDg==", + "dev": true, + "dependencies": { + "@nomiclabs/hardhat-docker": "^2.0.0", + "chalk": "4.1.2", + "dockerode": "^3.3.4" + }, + "peerDependencies": { + "hardhat": "^2.12.6" + } + }, + "node_modules/@matterlabs/hardhat-zksync-solc/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/@matterlabs/hardhat-zksync-solc/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/@matterlabs/hardhat-zksync-solc/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/@matterlabs/hardhat-zksync-solc/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/@matterlabs/hardhat-zksync-solc/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/@matterlabs/hardhat-zksync-solc/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/@matterlabs/hardhat-zksync-verify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.1.1.tgz", + "integrity": "sha512-RTV1tlyAGm/PZ30RLwiSODoZnduInelTSqTEjFE029s4zJJWmK4RZ1iscDdK5iPlsibMizQAEbu8ogQs3gTjMw==", + "dependencies": { + "@matterlabs/hardhat-zksync-solc": "0.3.12", + "axios": "^1.2.1", + "dockerode": "^3.3.4" + }, + "peerDependencies": { + "@nomiclabs/hardhat-etherscan": "3.1.2" + } + }, + "node_modules/@matterlabs/hardhat-zksync-verify/node_modules/@matterlabs/hardhat-zksync-solc": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.3.12.tgz", + "integrity": "sha512-0py4bsqphPYJV1Ub7jlCkMP2lEENIB16jv700rNnikJJn251ofQgzowcspJw+/WchP+Tu4tJSRL0a1MVngtCoQ==", + "dependencies": { + "@nomiclabs/hardhat-docker": "^2.0.0", + "dockerode": "^3.3.4" + }, + "peerDependencies": { + "hardhat": "^2.12.2" + } + }, "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", @@ -1304,29 +1548,29 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.0.3.tgz", - "integrity": "sha512-VFMiOQvsw7nx5bFmrmVp2Q9rhIjw2AFST4DYvWVVO9PMHPE23BY2+kyfrQ4J3xCMFC8fcBbGLt7l4q7m1SlTqg==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", + "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", "engines": { "node": ">= 12" }, "optionalDependencies": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.0.3", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.0.3", - "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.0.3" + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.0", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.0" } }, "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.0.3.tgz", - "integrity": "sha512-W+bIiNiZmiy+MTYFZn3nwjyPUO6wfWJ0lnXx2zZrM8xExKObMrhCh50yy8pQING24mHfpPFCn89wEB/iG7vZDw==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz", + "integrity": "sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==", "cpu": [ "arm64" ], @@ -1339,9 +1583,9 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.0.3.tgz", - "integrity": "sha512-HuJd1K+2MgmFIYEpx46uzwEFjvzKAI765mmoMxy4K+Aqq1p+q7hHRlsFU2kx3NB8InwotkkIq3A5FLU1sI1WDw==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz", + "integrity": "sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==", "cpu": [ "x64" ], @@ -1354,9 +1598,9 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.0.3.tgz", - "integrity": "sha512-2cR8JNy23jZaO/vZrsAnWCsO73asU7ylrHIe0fEsXbZYqBP9sMr+/+xP3CELDHJxUbzBY8zqGvQt1ULpyrG+Kw==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz", + "integrity": "sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==", "cpu": [ "x64" ], @@ -1369,9 +1613,9 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.0.3.tgz", - "integrity": "sha512-Eyv50EfYbFthoOb0I1568p+eqHGLwEUhYGOxcRNywtlTE9nj+c+MT1LA53HnxD9GsboH4YtOOmJOulrjG7KtbA==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz", + "integrity": "sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==", "cpu": [ "arm64" ], @@ -1384,9 +1628,9 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.0.3.tgz", - "integrity": "sha512-V8grDqI+ivNrgwEt2HFdlwqV2/EQbYAdj3hbOvjrA8Qv+nq4h9jhQUxFpegYMDtpU8URJmNNlXgtfucSrAQwtQ==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz", + "integrity": "sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==", "cpu": [ "arm64" ], @@ -1399,9 +1643,9 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.0.3.tgz", - "integrity": "sha512-uRfVDlxtwT1vIy7MAExWAkRD4r9M79zMG7S09mCrWUn58DbLs7UFl+dZXBX0/8FTGYWHhOT/1Etw1ZpAf5DTrg==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz", + "integrity": "sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==", "cpu": [ "x64" ], @@ -1414,9 +1658,9 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.0.3.tgz", - "integrity": "sha512-8HPwYdLbhcPpSwsE0yiU/aZkXV43vlXT2ycH+XlOjWOnLfH8C41z0njK8DHRtEFnp4OVN6E7E5lHBBKDZXCliA==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz", + "integrity": "sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==", "cpu": [ "x64" ], @@ -1429,9 +1673,9 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.0.3.tgz", - "integrity": "sha512-5WWcT6ZNvfCuxjlpZOY7tdvOqT1kIQYlDF9Q42wMpZ5aTm4PvjdCmFDDmmTvyXEBJ4WTVmY5dWNWaxy8h/E28g==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz", + "integrity": "sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==", "cpu": [ "arm64" ], @@ -1444,9 +1688,9 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.0.3.tgz", - "integrity": "sha512-P/LWGZwWkyjSwkzq6skvS2wRc3gabzAbk6Akqs1/Iiuggql2CqdLBkcYWL5Xfv3haynhL+2jlNkak+v2BTZI4A==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz", + "integrity": "sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==", "cpu": [ "ia32" ], @@ -1459,9 +1703,9 @@ } }, "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.0.3.tgz", - "integrity": "sha512-4AcTtLZG1s/S5mYAIr/sdzywdNwJpOcdStGF3QMBzEt+cGn3MchMaS9b1gyhb2KKM2c39SmPF5fUuWq1oBSQZQ==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz", + "integrity": "sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==", "cpu": [ "x64" ], @@ -1473,6 +1717,177 @@ "node": ">= 10" } }, + "node_modules/@nomiclabs/hardhat-docker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-docker/-/hardhat-docker-2.0.2.tgz", + "integrity": "sha512-XgGEpRT3wlA1VslyB57zyAHV+oll8KnV1TjwnxxC1tpAL04/lbdwpdO5KxInVN8irMSepqFpsiSkqlcnvbE7Ng==", + "dependencies": { + "dockerode": "^2.5.8", + "fs-extra": "^7.0.1", + "node-fetch": "^2.6.0" + } + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/bl/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/bl/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==", + "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/@nomiclabs/hardhat-docker/node_modules/bl/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==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/docker-modem": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-1.0.9.tgz", + "integrity": "sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw==", + "dependencies": { + "debug": "^3.2.6", + "JSONStream": "1.3.2", + "readable-stream": "~1.0.26-4", + "split-ca": "^1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/dockerode": { + "version": "2.5.8", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-2.5.8.tgz", + "integrity": "sha512-+7iOUYBeDTScmOmQqpUYQaE7F4vvIt6+gIZNHWhqAQEI887tiPFB9OvXI/HzQYqfUNvukMK+9myLW63oTJPZpw==", + "dependencies": { + "concat-stream": "~1.6.2", + "docker-modem": "^1.0.8", + "tar-fs": "~1.16.3" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/@nomiclabs/hardhat-docker/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==" + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "dependencies": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + } + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/tar-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/@nomiclabs/hardhat-docker/node_modules/tar-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==", + "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/@nomiclabs/hardhat-docker/node_modules/tar-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==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/@nomiclabs/hardhat-ethers": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.6.tgz", @@ -1487,7 +1902,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.2.tgz", "integrity": "sha512-IEikeOVq0C/7CY6aD74d8L4BpGoc/FNiN6ldiPVg0QIFIUSu4FSGA1dmtJZJKk1tjpwgrfTLQNWnigtEaN9REg==", - "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", @@ -1860,6 +2274,30 @@ "web3": "1.5.3" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "devOptional": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "devOptional": true + }, "node_modules/@typechain/ethers-v5": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", @@ -1941,9 +2379,9 @@ } }, "node_modules/@types/node": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", - "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==" + "version": "18.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", + "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==" }, "node_modules/@types/node-fetch": { "version": "2.6.2", @@ -2214,6 +2652,27 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "devOptional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.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==", + "devOptional": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/address": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/address/-/address-1.2.0.tgz", @@ -2345,6 +2804,12 @@ "node": ">= 8" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2415,7 +2880,6 @@ "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" } @@ -2460,7 +2924,6 @@ "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" } @@ -2490,8 +2953,7 @@ "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 + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/available-typed-arrays": { "version": "1.0.5", @@ -2520,6 +2982,29 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "node_modules/axios": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.3.tgz", + "integrity": "sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2562,7 +3047,6 @@ "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" } @@ -2570,8 +3054,7 @@ "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "node_modules/bech32": { "version": "1.1.4", @@ -2611,7 +3094,6 @@ "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": "*" } @@ -2624,6 +3106,16 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/blakejs": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", @@ -2825,7 +3317,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -2845,6 +3336,25 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -2869,6 +3379,26 @@ "node": ">=6.14.2" } }, + "node_modules/buildcheck": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.3.tgz", + "integrity": "sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==", + "optional": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2960,7 +3490,6 @@ "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" @@ -3047,8 +3576,7 @@ "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 + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/ci-info": { "version": "2.0.0", @@ -3192,7 +3720,6 @@ "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" }, @@ -3233,7 +3760,6 @@ "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" ], @@ -3248,7 +3774,6 @@ "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", @@ -3262,14 +3787,12 @@ "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 + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "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" } @@ -3329,8 +3852,7 @@ "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "node_modules/cors": { "version": "2.8.5", @@ -3345,6 +3867,20 @@ "node": ">= 0.10" } }, + "node_modules/cpu-features": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz", + "integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "buildcheck": "0.0.3", + "nan": "^2.15.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/crc-32": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", @@ -3397,6 +3933,12 @@ "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==", + "devOptional": true + }, "node_modules/cross-fetch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", @@ -3600,7 +4142,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -3702,6 +4243,33 @@ "node": ">=8" } }, + "node_modules/docker-modem": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.6.tgz", + "integrity": "sha512-h0Ow21gclbYsZ3mkHDfsYNDqtRhXS8fXr51bU0qr1dxgTMJj0XufbzX+jhNOvA8KuEEzn6JbvLVhXyv+fny9Uw==", + "dependencies": { + "debug": "^4.1.1", + "readable-stream": "^3.5.0", + "split-ca": "^1.0.1", + "ssh2": "^1.11.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/dockerode": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.4.tgz", + "integrity": "sha512-3EUwuXnCU+RUlQEheDjmBE0B7q66PV9Rw5NiH1sXwINq0M9c5ERP9fxgkw36ZHOtzf4AGEEYySnkx/sACC9EgQ==", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "docker-modem": "^3.0.0", + "tar-fs": "~2.0.1" + }, + "engines": { + "node": ">= 8.0" + } + }, "node_modules/dom-walk": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", @@ -3775,7 +4343,6 @@ "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" } @@ -3809,33 +4376,35 @@ } }, "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==", + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", + "integrity": "sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==", "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-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", + "gopd": "^1.0.1", "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-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", + "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", "unbox-primitive": "^1.0.2" }, "engines": { @@ -4861,9 +5430,9 @@ } }, "node_modules/ethers": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.1.tgz", - "integrity": "sha512-5krze4dRLITX7FpU8J4WscXqADiKmyeNlylmmDLbS95DaZpBhDe2YSwRQwKXWNyXcox7a3gBgm/MkGXV1O1S/Q==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", "dev": true, "funding": [ { @@ -4894,7 +5463,7 @@ "@ethersproject/networks": "5.7.1", "@ethersproject/pbkdf2": "5.7.0", "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.1", + "@ethersproject/providers": "5.7.2", "@ethersproject/random": "5.7.0", "@ethersproject/rlp": "5.7.0", "@ethersproject/sha2": "5.7.0", @@ -5078,8 +5647,7 @@ "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 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.2.11", @@ -5289,6 +5857,11 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "node_modules/fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", @@ -15618,9 +16191,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -15786,6 +16359,18 @@ "node": ">=8" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", @@ -15876,9 +16461,9 @@ } }, "node_modules/hardhat": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.11.2.tgz", - "integrity": "sha512-BdsXC1CFJQDJKmAgCwpmGhFuVU6dcqlgMgT0Kg/xmFAFVugkpYu6NRmh4AaJ3Fah0/BR9DOR4XgQGIbg4eon/Q==", + "version": "2.12.7", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.7.tgz", + "integrity": "sha512-voWoN6zn5d8BOEaczSyK/1PyfdeOeI3SbGCFb36yCHTJUt6OIqLb+ZDX30VhA1UsYKzLqG7UnWl3fKJUuANc6A==", "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", @@ -15892,7 +16477,7 @@ "@nomicfoundation/ethereumjs-tx": "^4.0.0", "@nomicfoundation/ethereumjs-util": "^8.0.0", "@nomicfoundation/ethereumjs-vm": "^6.0.0", - "@nomicfoundation/solidity-analyzer": "^0.0.3", + "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", @@ -15927,7 +16512,7 @@ "source-map-support": "^0.5.13", "stacktrace-parser": "^0.1.10", "tsort": "0.0.1", - "undici": "^5.4.0", + "undici": "^5.14.0", "uuid": "^8.3.2", "ws": "^7.4.6" }, @@ -16584,9 +17169,9 @@ } }, "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==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { "node": ">= 0.4" @@ -16897,8 +17482,7 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "node_modules/isexe": { "version": "2.0.0", @@ -16985,6 +17569,14 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ] + }, "node_modules/jsonschema": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", @@ -16994,6 +17586,21 @@ "node": "*" } }, + "node_modules/JSONStream": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha512-mn0KSip7N4e0UDPZHnqDsHECo5uGQrixQKnAskOM1BIB8hd7QKbd6il8IPRPudPHOeHiECoCFqhyMaRO9+nWyA==", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -17193,8 +17800,7 @@ "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -17306,6 +17912,12 @@ "yallist": "^3.0.2" } }, + "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==", + "devOptional": true + }, "node_modules/markdown-table": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", @@ -17432,7 +18044,6 @@ "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" } @@ -17441,7 +18052,6 @@ "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" }, @@ -17491,8 +18101,7 @@ "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 + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/minipass": { "version": "2.9.0", @@ -17517,7 +18126,6 @@ "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" }, @@ -17525,6 +18133,11 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/mkdirp-promise": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", @@ -17787,6 +18400,12 @@ "buffer": "^5.5.0" } }, + "node_modules/nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "optional": 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", @@ -17873,7 +18492,6 @@ "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" }, @@ -17903,7 +18521,6 @@ "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" } @@ -18023,14 +18640,14 @@ } }, "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==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -18484,8 +19101,7 @@ "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 + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/promise": { "version": "8.1.0", @@ -18509,6 +19125,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -18539,7 +19160,6 @@ "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" @@ -18549,7 +19169,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", - "dev": true, "engines": { "node": ">=6" } @@ -19087,6 +19706,20 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -19465,7 +20098,6 @@ "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", @@ -19482,7 +20114,6 @@ "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" }, @@ -19497,7 +20128,6 @@ "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" }, @@ -19508,8 +20138,7 @@ "node_modules/slice-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/solc": { "version": "0.6.12", @@ -19702,12 +20331,34 @@ "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", "dev": true }, + "node_modules/split-ca": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", + "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==" + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/ssh2": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz", + "integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==", + "hasInstallScript": true, + "dependencies": { + "asn1": "^0.2.4", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.4", + "nan": "^2.16.0" + } + }, "node_modules/sshpk": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", @@ -19775,6 +20426,14 @@ "node": ">=0.10.0" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.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", @@ -19806,28 +20465,28 @@ } }, "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==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" }, "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==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -20020,7 +20679,6 @@ "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -20036,7 +20694,6 @@ "version": "8.11.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -20051,8 +20708,7 @@ "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 + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/tar": { "version": "4.4.19", @@ -20072,6 +20728,32 @@ "node": ">=4.5" } }, + "node_modules/tar-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", + "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", @@ -20146,6 +20828,11 @@ "node": ">= 0.12" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, "node_modules/timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -20178,6 +20865,11 @@ "node": ">=0.6.0" } }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, "node_modules/to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", @@ -20237,8 +20929,7 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/ts-essentials": { "version": "1.0.4", @@ -20266,6 +20957,58 @@ "ts-generator": "dist/cli/run.js" } }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "devOptional": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -20379,8 +21122,7 @@ "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", @@ -20392,11 +21134,10 @@ } }, "node_modules/typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "devOptional": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -20446,9 +21187,12 @@ } }, "node_modules/undici": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.5.1.tgz", - "integrity": "sha512-MEvryPLf18HvlCbLSzCW0U00IMftKGI5udnjrQbC5D4P0Hodwffhv+iGfWuJwg16Y/TK11ZFK8i+BPVW2z/eAw==", + "version": "5.19.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.19.1.tgz", + "integrity": "sha512-YiZ61LPIgY73E7syxCDxxa3LV2yl3sN8spnIuTct60boiiRaE1J8mNWHO8Im2Zi/sFrPusjLlmRPrsyraSqX6A==", + "dependencies": { + "busboy": "^1.6.0" + }, "engines": { "node": ">=12.18" } @@ -20473,7 +21217,6 @@ "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" } @@ -20576,6 +21319,12 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": 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", @@ -21438,8 +22187,7 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/websocket": { "version": "1.0.34", @@ -21477,7 +22225,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -21738,7 +22485,6 @@ "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" } @@ -21804,6 +22550,15 @@ "node": ">=10" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": 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", @@ -21814,9 +22569,23 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zksync-web3": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/zksync-web3/-/zksync-web3-0.13.1.tgz", + "integrity": "sha512-+uHIBrK6UQ2+9I9ykH+aaPCBQJh80NOHX7tlDXVxDSWLIxaGGCMYuL4Kow1ZjrsLabIfSNpReJFLdhy87y0eGQ==", + "dev": true, + "peerDependencies": { + "ethers": "^5.7.0" + } } }, "dependencies": { + "@balena/dockerignore": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", + "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==" + }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -21824,6 +22593,15 @@ "dev": true, "optional": true }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, "@ensdomains/ens": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", @@ -22301,9 +23079,9 @@ } }, "@ethersproject/providers": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.1.tgz", - "integrity": "sha512-vZveG/DLyo+wk4Ga1yx6jSEHrLPgmTt+dFv0dv8URpVCRf0jVhalps1jq/emN/oXnMRsC7cQgAF32DcXLL7BPQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", "dev": true, "requires": { "@ethersproject/abstract-provider": "^5.7.0", @@ -22470,6 +23248,171 @@ "@ethersproject/strings": "^5.7.0" } }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "devOptional": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "devOptional": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@matterlabs/hardhat-zksync-deploy": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@matterlabs/hardhat-zksync-deploy/-/hardhat-zksync-deploy-0.6.1.tgz", + "integrity": "sha512-5uVcJGAc5cjWB1GjrUC/XAmF/03+QhoCaZiZA6HplgTJ9bzSWZ+Zzr+B18TFUD8+4fL8iBdstVlhw3C4j0/QLg==", + "dev": true, + "requires": { + "chalk": "4.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@matterlabs/hardhat-zksync-solc": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.3.14.tgz", + "integrity": "sha512-iKuQ+vvnpv3K2lkFO41xpJcNWH0KHJ/5JbOboTlPZATVR7F3GJeHfJL+GG4wkxKXnxZczpxyQqC4rAfMKvRaDg==", + "dev": true, + "requires": { + "@nomiclabs/hardhat-docker": "^2.0.0", + "chalk": "4.1.2", + "dockerode": "^3.3.4" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@matterlabs/hardhat-zksync-verify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.1.1.tgz", + "integrity": "sha512-RTV1tlyAGm/PZ30RLwiSODoZnduInelTSqTEjFE029s4zJJWmK4RZ1iscDdK5iPlsibMizQAEbu8ogQs3gTjMw==", + "requires": { + "@matterlabs/hardhat-zksync-solc": "0.3.12", + "axios": "^1.2.1", + "dockerode": "^3.3.4" + }, + "dependencies": { + "@matterlabs/hardhat-zksync-solc": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.3.12.tgz", + "integrity": "sha512-0py4bsqphPYJV1Ub7jlCkMP2lEENIB16jv700rNnikJJn251ofQgzowcspJw+/WchP+Tu4tJSRL0a1MVngtCoQ==", + "requires": { + "@nomiclabs/hardhat-docker": "^2.0.0", + "dockerode": "^3.3.4" + } + } + } + }, "@metamask/eth-sig-util": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", @@ -22690,82 +23633,250 @@ } }, "@nomicfoundation/solidity-analyzer": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.0.3.tgz", - "integrity": "sha512-VFMiOQvsw7nx5bFmrmVp2Q9rhIjw2AFST4DYvWVVO9PMHPE23BY2+kyfrQ4J3xCMFC8fcBbGLt7l4q7m1SlTqg==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", + "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", "requires": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.0.3", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.0.3", - "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.0.3" + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.0", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.0" } }, "@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.0.3.tgz", - "integrity": "sha512-W+bIiNiZmiy+MTYFZn3nwjyPUO6wfWJ0lnXx2zZrM8xExKObMrhCh50yy8pQING24mHfpPFCn89wEB/iG7vZDw==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz", + "integrity": "sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==", "optional": true }, "@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.0.3.tgz", - "integrity": "sha512-HuJd1K+2MgmFIYEpx46uzwEFjvzKAI765mmoMxy4K+Aqq1p+q7hHRlsFU2kx3NB8InwotkkIq3A5FLU1sI1WDw==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz", + "integrity": "sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==", "optional": true }, "@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.0.3.tgz", - "integrity": "sha512-2cR8JNy23jZaO/vZrsAnWCsO73asU7ylrHIe0fEsXbZYqBP9sMr+/+xP3CELDHJxUbzBY8zqGvQt1ULpyrG+Kw==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz", + "integrity": "sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==", "optional": true }, "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.0.3.tgz", - "integrity": "sha512-Eyv50EfYbFthoOb0I1568p+eqHGLwEUhYGOxcRNywtlTE9nj+c+MT1LA53HnxD9GsboH4YtOOmJOulrjG7KtbA==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz", + "integrity": "sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==", "optional": true }, "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.0.3.tgz", - "integrity": "sha512-V8grDqI+ivNrgwEt2HFdlwqV2/EQbYAdj3hbOvjrA8Qv+nq4h9jhQUxFpegYMDtpU8URJmNNlXgtfucSrAQwtQ==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz", + "integrity": "sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==", "optional": true }, "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.0.3.tgz", - "integrity": "sha512-uRfVDlxtwT1vIy7MAExWAkRD4r9M79zMG7S09mCrWUn58DbLs7UFl+dZXBX0/8FTGYWHhOT/1Etw1ZpAf5DTrg==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz", + "integrity": "sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==", "optional": true }, "@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.0.3.tgz", - "integrity": "sha512-8HPwYdLbhcPpSwsE0yiU/aZkXV43vlXT2ycH+XlOjWOnLfH8C41z0njK8DHRtEFnp4OVN6E7E5lHBBKDZXCliA==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz", + "integrity": "sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==", "optional": true }, "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.0.3.tgz", - "integrity": "sha512-5WWcT6ZNvfCuxjlpZOY7tdvOqT1kIQYlDF9Q42wMpZ5aTm4PvjdCmFDDmmTvyXEBJ4WTVmY5dWNWaxy8h/E28g==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz", + "integrity": "sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==", "optional": true }, "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.0.3.tgz", - "integrity": "sha512-P/LWGZwWkyjSwkzq6skvS2wRc3gabzAbk6Akqs1/Iiuggql2CqdLBkcYWL5Xfv3haynhL+2jlNkak+v2BTZI4A==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz", + "integrity": "sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==", "optional": true }, "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.0.3.tgz", - "integrity": "sha512-4AcTtLZG1s/S5mYAIr/sdzywdNwJpOcdStGF3QMBzEt+cGn3MchMaS9b1gyhb2KKM2c39SmPF5fUuWq1oBSQZQ==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz", + "integrity": "sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==", "optional": true }, + "@nomiclabs/hardhat-docker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-docker/-/hardhat-docker-2.0.2.tgz", + "integrity": "sha512-XgGEpRT3wlA1VslyB57zyAHV+oll8KnV1TjwnxxC1tpAL04/lbdwpdO5KxInVN8irMSepqFpsiSkqlcnvbE7Ng==", + "requires": { + "dockerode": "^2.5.8", + "fs-extra": "^7.0.1", + "node-fetch": "^2.6.0" + }, + "dependencies": { + "bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "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==", + "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" + } + }, + "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==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "docker-modem": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-1.0.9.tgz", + "integrity": "sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw==", + "requires": { + "debug": "^3.2.6", + "JSONStream": "1.3.2", + "readable-stream": "~1.0.26-4", + "split-ca": "^1.0.0" + } + }, + "dockerode": { + "version": "2.5.8", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-2.5.8.tgz", + "integrity": "sha512-+7iOUYBeDTScmOmQqpUYQaE7F4vvIt6+gIZNHWhqAQEI887tiPFB9OvXI/HzQYqfUNvukMK+9myLW63oTJPZpw==", + "requires": { + "concat-stream": "~1.6.2", + "docker-modem": "^1.0.8", + "tar-fs": "~1.16.3" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "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==" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "requires": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "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==", + "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" + } + }, + "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==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + } + } + }, "@nomiclabs/hardhat-ethers": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.6.tgz", @@ -22777,7 +23888,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.2.tgz", "integrity": "sha512-IEikeOVq0C/7CY6aD74d8L4BpGoc/FNiN6ldiPVg0QIFIUSu4FSGA1dmtJZJKk1tjpwgrfTLQNWnigtEaN9REg==", - "dev": true, "requires": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", @@ -23107,6 +24217,30 @@ "web3": "1.5.3" } }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "devOptional": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "devOptional": true + }, "@typechain/ethers-v5": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", @@ -23184,9 +24318,9 @@ } }, "@types/node": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", - "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==" + "version": "18.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", + "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==" }, "@types/node-fetch": { "version": "2.6.2", @@ -23416,6 +24550,18 @@ "negotiator": "0.6.3" } }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "devOptional": true + }, + "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==", + "devOptional": true + }, "address": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/address/-/address-1.2.0.tgz", @@ -23510,6 +24656,12 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -23565,7 +24717,6 @@ "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" } @@ -23605,8 +24756,7 @@ "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 + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" }, "async": { "version": "2.6.4", @@ -23633,8 +24783,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "available-typed-arrays": { "version": "1.0.5", @@ -23654,6 +24803,28 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "axios": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.3.tgz", + "integrity": "sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -23682,7 +24853,6 @@ "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" }, @@ -23690,8 +24860,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" } } }, @@ -23723,14 +24892,23 @@ "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 + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "blakejs": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", @@ -23923,12 +25101,30 @@ "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-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -23949,6 +25145,20 @@ "node-gyp-build": "^4.3.0" } }, + "buildcheck": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.3.tgz", + "integrity": "sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==", + "optional": true + }, + "busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "requires": { + "streamsearch": "^1.1.0" + } + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -24015,7 +25225,6 @@ "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" @@ -24076,8 +25285,7 @@ "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "ci-info": { "version": "2.0.0", @@ -24199,7 +25407,6 @@ "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" } @@ -24234,7 +25441,6 @@ "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", @@ -24246,7 +25452,6 @@ "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", @@ -24260,14 +25465,12 @@ "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 + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "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" } @@ -24320,8 +25523,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "cors": { "version": "2.8.5", @@ -24333,6 +25535,16 @@ "vary": "^1" } }, + "cpu-features": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz", + "integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==", + "optional": true, + "requires": { + "buildcheck": "0.0.3", + "nan": "^2.15.0" + } + }, "crc-32": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", @@ -24381,6 +25593,12 @@ "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==", + "devOptional": true + }, "cross-fetch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", @@ -24538,8 +25756,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "depd": { "version": "2.0.0", @@ -24622,6 +25839,27 @@ "path-type": "^4.0.0" } }, + "docker-modem": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.6.tgz", + "integrity": "sha512-h0Ow21gclbYsZ3mkHDfsYNDqtRhXS8fXr51bU0qr1dxgTMJj0XufbzX+jhNOvA8KuEEzn6JbvLVhXyv+fny9Uw==", + "requires": { + "debug": "^4.1.1", + "readable-stream": "^3.5.0", + "split-ca": "^1.0.1", + "ssh2": "^1.11.0" + } + }, + "dockerode": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.4.tgz", + "integrity": "sha512-3EUwuXnCU+RUlQEheDjmBE0B7q66PV9Rw5NiH1sXwINq0M9c5ERP9fxgkw36ZHOtzf4AGEEYySnkx/sACC9EgQ==", + "requires": { + "@balena/dockerignore": "^1.0.2", + "docker-modem": "^3.0.0", + "tar-fs": "~2.0.1" + } + }, "dom-walk": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", @@ -24691,7 +25929,6 @@ "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" } @@ -24719,33 +25956,35 @@ } }, "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==", + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", + "integrity": "sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==", "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-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", + "gopd": "^1.0.1", "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-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", + "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", "unbox-primitive": "^1.0.2" } }, @@ -25575,9 +26814,9 @@ } }, "ethers": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.1.tgz", - "integrity": "sha512-5krze4dRLITX7FpU8J4WscXqADiKmyeNlylmmDLbS95DaZpBhDe2YSwRQwKXWNyXcox7a3gBgm/MkGXV1O1S/Q==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", "dev": true, "requires": { "@ethersproject/abi": "5.7.0", @@ -25598,7 +26837,7 @@ "@ethersproject/networks": "5.7.1", "@ethersproject/pbkdf2": "5.7.0", "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.1", + "@ethersproject/providers": "5.7.2", "@ethersproject/random": "5.7.0", "@ethersproject/rlp": "5.7.0", "@ethersproject/sha2": "5.7.0", @@ -25762,8 +27001,7 @@ "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 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { "version": "3.2.11", @@ -25930,6 +27168,11 @@ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", @@ -33832,9 +35075,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -33963,6 +35206,15 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", @@ -34031,9 +35283,9 @@ } }, "hardhat": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.11.2.tgz", - "integrity": "sha512-BdsXC1CFJQDJKmAgCwpmGhFuVU6dcqlgMgT0Kg/xmFAFVugkpYu6NRmh4AaJ3Fah0/BR9DOR4XgQGIbg4eon/Q==", + "version": "2.12.7", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.7.tgz", + "integrity": "sha512-voWoN6zn5d8BOEaczSyK/1PyfdeOeI3SbGCFb36yCHTJUt6OIqLb+ZDX30VhA1UsYKzLqG7UnWl3fKJUuANc6A==", "requires": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", @@ -34047,7 +35299,7 @@ "@nomicfoundation/ethereumjs-tx": "^4.0.0", "@nomicfoundation/ethereumjs-util": "^8.0.0", "@nomicfoundation/ethereumjs-vm": "^6.0.0", - "@nomicfoundation/solidity-analyzer": "^0.0.3", + "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", @@ -34082,7 +35334,7 @@ "source-map-support": "^0.5.13", "stacktrace-parser": "^0.1.10", "tsort": "0.0.1", - "undici": "^5.4.0", + "undici": "^5.14.0", "uuid": "^8.3.2", "ws": "^7.4.6" }, @@ -34554,9 +35806,9 @@ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" }, "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true }, "is-ci": { @@ -34758,8 +36010,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", @@ -34840,12 +36091,26 @@ "graceful-fs": "^4.1.6" } }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==" + }, "jsonschema": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", "dev": true }, + "JSONStream": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha512-mn0KSip7N4e0UDPZHnqDsHECo5uGQrixQKnAskOM1BIB8hd7QKbd6il8IPRPudPHOeHiECoCFqhyMaRO9+nWyA==", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, "jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -34997,8 +36262,7 @@ "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" }, "log-symbols": { "version": "4.1.0", @@ -35082,6 +36346,12 @@ "yallist": "^3.0.2" } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true + }, "markdown-table": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", @@ -35179,14 +36449,12 @@ "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 + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "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" } @@ -35227,8 +36495,7 @@ "minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "minipass": { "version": "2.9.0", @@ -35253,11 +36520,15 @@ "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-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "mkdirp-promise": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", @@ -35452,6 +36723,12 @@ } } }, + "nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "optional": 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", @@ -35528,7 +36805,6 @@ "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" } @@ -35541,8 +36817,7 @@ "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 + "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==" }, "nopt": { "version": "3.0.6", @@ -35632,14 +36907,14 @@ "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==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } }, @@ -35971,8 +37246,7 @@ "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 + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "promise": { "version": "8.1.0", @@ -35993,6 +37267,11 @@ "ipaddr.js": "1.9.1" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -36025,7 +37304,6 @@ "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" @@ -36034,8 +37312,7 @@ "punycode": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", - "dev": true + "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==" }, "qs": { "version": "6.11.0", @@ -36409,6 +37686,17 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -36716,7 +38004,6 @@ "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", @@ -36727,7 +38014,6 @@ "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" } @@ -36736,7 +38022,6 @@ "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" } @@ -36744,8 +38029,7 @@ "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" } } }, @@ -36916,12 +38200,28 @@ "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", "dev": true }, + "split-ca": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", + "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==" + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "ssh2": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz", + "integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==", + "requires": { + "asn1": "^0.2.4", + "bcrypt-pbkdf": "^1.0.2", + "cpu-features": "~0.0.4", + "nan": "^2.16.0" + } + }, "sshpk": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", @@ -36973,6 +38273,11 @@ "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", "dev": true }, + "streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -36998,25 +38303,25 @@ } }, "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==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "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==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "strip-ansi": { @@ -37168,7 +38473,6 @@ "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, "requires": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -37181,7 +38485,6 @@ "version": "8.11.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -37192,8 +38495,7 @@ "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 + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" } } }, @@ -37212,6 +38514,29 @@ "yallist": "^3.1.1" } }, + "tar-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", + "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, "test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", @@ -37277,6 +38602,11 @@ } } }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -37303,6 +38633,11 @@ "os-tmpdir": "~1.0.2" } }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, "to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", @@ -37349,8 +38684,7 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "ts-essentials": { "version": "1.0.4", @@ -37375,6 +38709,35 @@ "ts-essentials": "^1.0.0" } }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "devOptional": true, + "requires": { + "@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" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true + } + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -37467,8 +38830,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "typedarray-to-buffer": { "version": "3.1.5", @@ -37480,11 +38842,10 @@ } }, "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "devOptional": true, - "peer": true + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "devOptional": true }, "typical": { "version": "2.6.1", @@ -37518,9 +38879,12 @@ } }, "undici": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.5.1.tgz", - "integrity": "sha512-MEvryPLf18HvlCbLSzCW0U00IMftKGI5udnjrQbC5D4P0Hodwffhv+iGfWuJwg16Y/TK11ZFK8i+BPVW2z/eAw==" + "version": "5.19.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.19.1.tgz", + "integrity": "sha512-YiZ61LPIgY73E7syxCDxxa3LV2yl3sN8spnIuTct60boiiRaE1J8mNWHO8Im2Zi/sFrPusjLlmRPrsyraSqX6A==", + "requires": { + "busboy": "^1.6.0" + } }, "universalify": { "version": "0.1.2", @@ -37536,7 +38900,6 @@ "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" } @@ -37625,6 +38988,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "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==", + "devOptional": 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", @@ -38401,8 +39770,7 @@ "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "websocket": { "version": "1.0.34", @@ -38439,7 +39807,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -38641,8 +40008,7 @@ "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { "version": "5.0.8", @@ -38690,10 +40056,23 @@ "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==", + "devOptional": 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==" + }, + "zksync-web3": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/zksync-web3/-/zksync-web3-0.13.1.tgz", + "integrity": "sha512-+uHIBrK6UQ2+9I9ykH+aaPCBQJh80NOHX7tlDXVxDSWLIxaGGCMYuL4Kow1ZjrsLabIfSNpReJFLdhy87y0eGQ==", + "dev": true, + "requires": {} } } } diff --git a/package.json b/package.json index 620aa48c..07283999 100644 --- a/package.json +++ b/package.json @@ -12,23 +12,32 @@ "compile": "npx hardhat compile" }, "devDependencies": { + "@ethersproject/hash": "^5.7.0", + "@ethersproject/web": "^5.7.1", + "@matterlabs/hardhat-zksync-deploy": "^0.6.1", + "@matterlabs/hardhat-zksync-solc": "^0.3.14", "@nomiclabs/hardhat-ethers": "^2.0.0", "@nomiclabs/hardhat-etherscan": "^3.1.2", "@nomiclabs/hardhat-waffle": "^2.0.0", + "@types/node": "^18.13.0", "@uniswap/sdk-core": "^3.0.1", "@uniswap/v3-sdk": "^3.4.1", "chai": "^4.2.0", "cross-fetch": "^3.1.4", "ethereum-block-by-date": "^1.4.2", "ethereum-waffle": "^3.3.0", - "ethers": "^5.7.0", + "ethers": "^5.7.2", "ganache-cli": "^6.12.1", - "hardhat": "^2.10.2", + "hardhat": "^2.12.7", "hardhat-contract-sizer": "^2.0.3", "hardhat-gas-reporter": "^1.0.6", - "solidity-coverage": "^0.7.16" + "solidity-coverage": "^0.7.16", + "ts-node": "^10.9.1", + "typescript": "^4.9.5", + "zksync-web3": "^0.13.1" }, "dependencies": { + "@matterlabs/hardhat-zksync-verify": "^0.1.1", "dotenv": "^8.2.0", "hardhat-spdx-license-identifier": "^2.0.3", "seedrandom": "^3.0.5" diff --git a/scripts/zksync-setup.js b/scripts/zksync-setup.js new file mode 100644 index 00000000..571ba28d --- /dev/null +++ b/scripts/zksync-setup.js @@ -0,0 +1,551 @@ +const hre = require("hardhat"); +const { utils, Wallet } = require("zksync-web3"); +const { Deployer } = require("@matterlabs/hardhat-zksync-deploy"); +const { moduleIds, eth, contractNames, AddressZero, HashZero, writeAddressManifestToFile } = require("../test/lib/eTestLib"); + +const fs = require("fs"); +const child_process = require("child_process"); + +const { Route, Pool, FeeAmount, TICK_SPACINGS, encodeRouteToPath, nearestUsableTick, TickMath } = require('@uniswap/v3-sdk'); +const { Token, CurrencyAmount } = require('@uniswap/sdk-core'); +const { ethers } = require("hardhat"); + +const defaultUniswapFee = FeeAmount.MEDIUM; + +async function main() { + + // usage + // NETWORK_NAME=testing-small npx hardhat run scripts/zkSync-setup.js --network zktestnet + let networkName = process.env.NETWORK_NAME; + + const ctx = await deployContracts(networkName); + + writeAddressManifestToFile(ctx, `./euler-addresses-${networkName}.json`); +} + +async function deployContracts(tokenSetupName) { + + let verification = { + contracts: { + tokens: {}, + oracles: {}, + modules: {}, + swapHandlers: {} + }, + }; + + // Initialize the wallet. + const wallet = new Wallet(process.env.ZK_PRIVATE_KEY, hre.ethers.provider); + + // Create deployer object and load the + // artifact of the contract we want to deploy. + const deployer = new Deployer(hre, wallet); + + let ctx = await buildContext(deployer, wallet, tokenSetupName); + + let gitCommit = ethers.utils.hexZeroPad('0x' + child_process.execSync('git rev-parse HEAD').toString().trim(), 32); + + + // Uni V3 router + let swapRouterV2Address = AddressZero; + let swapRouterV3Address = AddressZero; + let swapRouter02Address = AddressZero; + let oneInchAddress = AddressZero; + + if (ctx.tokenSetup.testing) { + // Default tokens + + for (let token of (ctx.tokenSetup.testing.tokens || [])) { + const artifact = await deployer.loadArtifact("TestERC20"); + const constructorArguments = [token.name, token.symbol, token.decimals, false]; + const contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.tokens[token.symbol] = contract; + verification.contracts.tokens[token.symbol] = contract.interface.encodeDeploy(constructorArguments); + + + // if price oracle for the token is chainlink, + // deploy mock chainlink price oracle + + if (ctx.tokenSetup.testing.chainlinkOracles && ctx.tokenSetup.testing.chainlinkOracles.includes(token.symbol)) { + const artifact = await deployer.loadArtifact("MockAggregatorProxy"); + const constructorArguments = [18]; + const contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.oracles[token.symbol] = contract; + verification.contracts.oracles[token.symbol] = contract.interface.encodeDeploy(constructorArguments); + } + } + + // Libraries and testing + + // FIX-ME: To setup real uniswap contracts with abi from zkSync compiler + // we need to get the .sol files from uniswap repo so they have to be compiled by zksolc + // if (ctx.tokenSetup.testing.useRealUniswap) { + // { + // const { abi, bytecode, } = require('../vendor-artifacts/UniswapV3Factory.json'); + // ctx.uniswapV3FactoryFactory = new ethers.ContractFactory(abi, bytecode, ctx.wallet); + // ctx.contracts.uniswapV3Factory = await (await ctx.uniswapV3FactoryFactory.deploy()).deployed(); + // verification.contracts.uniswapV3Factory = { + // address: ctx.contracts.uniswapV3Factory.address, args: [] + // }; + // } + // { + // const { abi, bytecode, } = require('../vendor-artifacts/SwapRouterV3.json'); + // ctx.SwapRouterFactory = new ethers.ContractFactory(abi, bytecode, ctx.wallet); + // ctx.contracts.swapRouterV3 = await (await ctx.SwapRouterFactory.deploy(ctx.contracts.uniswapV3Factory.address, ctx.contracts.tokens['WETH'].address)).deployed(); + // verification.contracts.swapRouterV3 = { + // address: ctx.contracts.swapRouterV3.address, args: [ctx.contracts.uniswapV3Factory.address, ctx.contracts.tokens['WETH'].address] + // }; + // } + // { + // const { abi, bytecode, } = require('../vendor-artifacts/SwapRouter02.json'); + // ctx.SwapRouter02Factory = new ethers.ContractFactory(abi, bytecode, ctx.wallet); + // ctx.contracts.swapRouter02 = await (await ctx.SwapRouter02Factory.deploy( + // AddressZero, // factoryV2 not needed + // ctx.contracts.uniswapV3Factory.address, + // AddressZero, // positionManager not needed + // ctx.contracts.tokens['WETH'].address + // )).deployed(); + // verification.contracts.swapRouter02 = { + // address: ctx.contracts.swapRouter02.address, + // args: [ + // AddressZero, + // ctx.contracts.uniswapV3Factory.address, + // AddressZero, + // ctx.contracts.tokens['WETH'].address + // ] + // }; + // } + // { + // const { abi, bytecode, } = require('../vendor-artifacts/UniswapV3Pool.json'); + // ctx.uniswapV3PoolByteCodeHash = ethers.utils.keccak256(bytecode); + // } + + // swapRouterV3Address = ctx.contracts.swapRouterV3.address; + // swapRouter02Address = ctx.contracts.swapRouter02.address; + // } else { + // // FIX-ME: market activation with uniswap factory failing due to address computation issues with zkSync + // const artifact = await deployer.loadArtifact("MockUniswapV3Factory"); + // const constructorArguments = []; + // const contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + // ctx.contracts.uniswapV3Factory = contract; + // verification.contracts.uniswapV3Factory = contract.interface.encodeDeploy(constructorArguments); + + // ctx.uniswapV3PoolByteCodeHash = ethers.utils.keccak256((await deployer.loadArtifact("MockUniswapV3Pool")).bytecode); + // } + + let artifact = await deployer.loadArtifact("InvariantChecker"); + let constructorArguments = []; + let contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.invariantChecker = contract; + verification.contracts.invariantChecker = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("FlashLoanNativeTest"); + constructorArguments = []; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.flashLoanNativeTest = contract; + verification.contracts.flashLoanNativeTest = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("FlashLoanAdaptorTest"); + constructorArguments = []; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.flashLoanAdaptorTest = contract; + verification.contracts.flashLoanAdaptorTest = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("FlashLoanAdaptorTest"); + constructorArguments = []; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.flashLoanAdaptorTest2 = contract; + verification.contracts.flashLoanAdaptorTest2 = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("SimpleUniswapPeriphery"); + constructorArguments = []; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.simpleUniswapPeriphery = contract; + verification.contracts.simpleUniswapPeriphery = contract.interface.encodeDeploy(constructorArguments); + + // Setup uniswap pairs + + // for (let pair of ctx.tokenSetup.testing.uniswapPools) { + // await ctx.createUniswapPool(pair, defaultUniswapFee); + // } + + // FIX-ME: uncomment after above useRealUniswap branch is fixed + // Initialize uniswap pools for tokens we will activate + // if (ctx.tokenSetup.testing.useRealUniswap) { + // for (let tok of ctx.tokenSetup.testing.activated) { + // if (tok === 'WETH') continue; + // let config = ctx.tokenSetup.testing.tokens.find(t => t.symbol === tok) + // await ctx.contracts.uniswapPools[`${tok}/WETH`].initialize( + // ctx.poolAdjustedRatioToSqrtPriceX96(`${tok}/WETH`, 10**(18 - config.decimals), + // 1, + // )); + // } + // } + } + + // Euler Contracts + + // Create module implementations + + let riskManagerSettings; + + if (ctx.tokenSetup.riskManagerSettings) { + riskManagerSettings = ctx.tokenSetup.riskManagerSettings; + + // Deployment without Uniswap (Factory) + if (riskManagerSettings.uniswapFactory === AddressZero) { + riskManagerSettings.uniswapFactory = riskManagerSettings.uniswapFactory; + riskManagerSettings.uniswapPoolInitCodeHash = HashZero; + } + + if (!riskManagerSettings.referenceAsset) { + riskManagerSettings.referenceAsset = ctx.contracts.tokens['WETH'].address; + } + } else { + riskManagerSettings = { + referenceAsset: ctx.contracts.tokens['WETH'].address, + uniswapFactory: ctx.contracts.uniswapV3Factory.address, + uniswapPoolInitCodeHash: ctx.uniswapV3PoolByteCodeHash, + }; + } + + if (ctx.tokenSetup.existingContracts) { + if (ctx.tokenSetup.existingContracts.swapRouterV2) swapRouterV2Address = ctx.tokenSetup.existingContracts.swapRouterV2; + if (ctx.tokenSetup.existingContracts.swapRouterV3) swapRouterV3Address = ctx.tokenSetup.existingContracts.swapRouterV3; + if (ctx.tokenSetup.existingContracts.swapRouter02) swapRouter02Address = ctx.tokenSetup.existingContracts.swapRouter02; + if (ctx.tokenSetup.existingContracts.oneInch) oneInchAddress = ctx.tokenSetup.existingContracts.oneInch; + } + + let artifact = await deployer.loadArtifact("RiskManager"); + let constructorArguments = [gitCommit, riskManagerSettings]; + let contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.riskManager = contract; + verification.contracts.modules.riskManager = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("Installer"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.installer = contract; + verification.contracts.modules.installer = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("Markets"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.markets = contract; + verification.contracts.modules.markets = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("Liquidation"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.liquidation = contract; + verification.contracts.modules.liquidation = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("Governance"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.governance = contract; + verification.contracts.modules.governance = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("Exec"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.exec = contract; + verification.contracts.modules.exec = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("Swap"); + constructorArguments = [gitCommit, swapRouterV3Address, oneInchAddress]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.swap = contract; + verification.contracts.modules.swap = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("SwapHub"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.swapHub = contract; + verification.contracts.modules.swapHub = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("EToken"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.eToken = contract; + verification.contracts.modules.eToken = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("DToken"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.dToken = contract; + verification.contracts.modules.dToken = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("IRMDefault"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.irmDefault = contract; + verification.contracts.modules.irmDefault = contract.interface.encodeDeploy(constructorArguments); + + if (ctx.tokenSetup.testing) { + let artifact = await deployer.loadArtifact("IRMZero"); + let constructorArguments = [gitCommit]; + let contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.irmZero = contract; + verification.contracts.modules.irmZero = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("IRMFixed"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.irmFixed = contract; + verification.contracts.modules.irmFixed = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("IRMLinear"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.modules.irmLinear = contract; + verification.contracts.modules.irmLinear = contract.interface.encodeDeploy(constructorArguments); + } + + // Create euler contract, which also installs the installer module and creates a proxy + + artifact = await deployer.loadArtifact("Euler"); + constructorArguments = [wallet.address, ctx.contracts.modules.installer.address]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.euler = contract; + verification.contracts.euler = contract.interface.encodeDeploy(constructorArguments); + + + // Create euler view contracts + + artifact = await deployer.loadArtifact("EulerSimpleLens"); + constructorArguments = [gitCommit, ctx.contracts.euler.address]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.eulerSimpleLens = contract; + verification.contracts.eulerSimpleLens = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("DeltaBalances"); + constructorArguments = []; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.deltaBalances = contract; + verification.contracts.deltaBalances = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("EulerGeneralView"); + constructorArguments = [gitCommit]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.eulerGeneralView = contract; + verification.contracts.eulerGeneralView = contract.interface.encodeDeploy(constructorArguments); + + // Get reference to installer proxy + artifact = await deployer.loadArtifact("Installer"); + ctx.contracts.installer = await ethers.getContractAt('Installer', await ctx.contracts.euler.moduleIdToProxy(moduleIds.INSTALLER)); + + // Install the remaining modules + + { + let modulesToInstall = [ + 'markets', + 'liquidation', + 'governance', + 'exec', + 'swap', + 'swapHub', + + 'eToken', + 'dToken', + + 'riskManager', + + 'irmDefault', + ]; + + if (ctx.tokenSetup.testing) { + modulesToInstall.push( + 'irmZero', + 'irmFixed', + 'irmLinear', + ); + } + + let moduleAddrs = modulesToInstall.map(m => ctx.contracts.modules[m].address); + + await (await ctx.contracts.installer.connect(ctx.wallet).installModules(moduleAddrs)).wait(); + } + + // Get references to external single proxies + + ctx.contracts.markets = await ethers.getContractAt('Markets', await ctx.contracts.euler.moduleIdToProxy(moduleIds.MARKETS)); + ctx.contracts.liquidation = await ethers.getContractAt('Liquidation', await ctx.contracts.euler.moduleIdToProxy(moduleIds.LIQUIDATION)); + ctx.contracts.governance = await ethers.getContractAt('Governance', await ctx.contracts.euler.moduleIdToProxy(moduleIds.GOVERNANCE)); + ctx.contracts.exec = await ethers.getContractAt('Exec', await ctx.contracts.euler.moduleIdToProxy(moduleIds.EXEC)); + ctx.contracts.swap = await ethers.getContractAt('Swap', await ctx.contracts.euler.moduleIdToProxy(moduleIds.SWAP)); + ctx.contracts.swapHub = await ethers.getContractAt('SwapHub', await ctx.contracts.euler.moduleIdToProxy(moduleIds.SWAP_HUB)); + + + // Deploy swap handlers + + artifact = await deployer.loadArtifact("SwapHandlerUniswapV3"); + constructorArguments = [swapRouterV3Address]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.swapHandlers.swapHandlerUniswapV3 = contract; + verification.contracts.swapHandlers.swapHandlerUniswapV3 = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("SwapHandler1Inch"); + constructorArguments = [oneInchAddress, swapRouterV2Address, swapRouterV3Address]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.swapHandlers.swapHandler1Inch = contract; + verification.contracts.swapHandlers.swapHandler1Inch = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("SwapHandlerUniAutoRouter"); + constructorArguments = [swapRouter02Address, swapRouterV2Address, swapRouterV3Address]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.swapHandlers.swapHandlerUniAutoRouter = contract; + verification.contracts.swapHandlers.swapHandlerUniAutoRouter = contract.interface.encodeDeploy(constructorArguments); + + if (ctx.tokenSetup.testing) { + // Setup default ETokens/DTokens + + for (let tok of ctx.tokenSetup.testing.activated) { + if (ctx.tokenSetup.testing.chainlinkOracles && ctx.tokenSetup.testing.chainlinkOracles.includes(tok)) { + await ctx.activateMarketWithChainlinkPriceFeed(tok, ctx.contracts.oracles[tok].address); + if (ctx.tokenSetup.testing.chainlinkPrices[tok]) { + await ctx.contracts.oracles[tok].connect(ctx.wallet).mockSetValidAnswer(eth(ctx.tokenSetup.testing.chainlinkPrices[tok].toString())); + } + } else { + // FIX-ME: only used for reference asset + // failing for other tokens/markets due to address computation issues with zkSync + await ctx.activateMarket(tok); + } + } + + for (let tok of (ctx.tokenSetup.testing.tokens || [])) { + if (tok.config) { + if (!ctx.tokenSetup.testing.activated.find(s => s === tok.symbol)) throw(`can't set config for unactivated asset: ${tok.symbol}`); + await ctx.setAssetConfig(ctx.contracts.tokens[tok.symbol].address, tok.config); + } + } + } + + // Setup adaptors + + artifact = await deployer.loadArtifact("FlashLoan"); + constructorArguments = [ + ctx.contracts.euler.address, + ctx.contracts.exec.address, + ctx.contracts.markets.address, + ]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.flashLoan = contract; + verification.contracts.flashLoan = contract.interface.encodeDeploy(constructorArguments); + + // Setup liquidity mining contracts + + if (ctx.contracts.tokens.EUL) { + let artifact = await deployer.loadArtifact("EulStakes"); + let constructorArguments = [ + ctx.contracts.tokens.EUL.address + ]; + let contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.eulStakes = contract; + verification.contracts.eulStakes = contract.interface.encodeDeploy(constructorArguments); + + artifact = await deployer.loadArtifact("EulDistributor"); + constructorArguments = [ + ctx.contracts.tokens.EUL.address, + ctx.contracts.eulStakes.address, + ]; + contract = await (await deployer.deploy(artifact, constructorArguments)).deployed(); + ctx.contracts.eulDistributor = contract; + verification.contracts.eulDistributor = contract.interface.encodeDeploy(constructorArguments); + } + + // export verification json file for zkSync smart contract verification UI + let outputJson = JSON.stringify(verification, ' ', 4); + fs.writeFileSync(`./euler-contracts-verification-${tokenSetupName}.json`, outputJson + "\n"); + + return ctx; +} + + + +async function buildContext(deployer, wallet, tokenSetupName) { + let ctx = { + moduleIds, + wallet: wallet, + + contracts: { + tokens: {}, + oracles: {}, + eTokens: {}, + dTokens: {}, + uniswapPools: {}, + modules: {}, + swapHandlers: {} + }, + + uniswapPoolsInverted: {}, + }; + + // Token Setup + ctx.tokenSetup = require(`../test/lib/token-setups/${tokenSetupName}`); + + ctx.populateUniswapPool = async (pair, fee) => { + const addr = await ctx.contracts.uniswapV3Factory.getPool(ctx.contracts.tokens[pair[0]].address, ctx.contracts.tokens[pair[1]].address, fee); + + ctx.contracts.uniswapPools[`${pair[0]}/${pair[1]}`] = await ethers.getContractAt('MockUniswapV3Pool', addr); + ctx.contracts.uniswapPools[`${pair[1]}/${pair[0]}`] = await ethers.getContractAt('MockUniswapV3Pool', addr); + + let inverted = ethers.BigNumber.from(ctx.contracts.tokens[pair[0]].address).gt(ctx.contracts.tokens[pair[1]].address); + ctx.uniswapPoolsInverted[`${pair[0]}/${pair[1]}`] = !inverted; + ctx.uniswapPoolsInverted[`${pair[1]}/${pair[0]}`] = inverted; + }; + + ctx.createUniswapPool = async (pair, fee) => { + await (await ctx.contracts.uniswapV3Factory.createPool(ctx.contracts.tokens[pair[0]].address, ctx.contracts.tokens[pair[1]].address, fee)).wait(); + return ctx.populateUniswapPool(pair, fee); + } + + ctx.setAssetConfig = async (underlying, newConfig) => { + let config = await ctx.contracts.markets.underlyingToAssetConfigUnresolved(underlying); + + config = { + eTokenAddress: config.eTokenAddress, + borrowIsolated: config.borrowIsolated, + collateralFactor: config.collateralFactor, + borrowFactor: config.borrowFactor, + twapWindow: config.twapWindow, + }; + + if (newConfig.collateralFactor !== undefined) config.collateralFactor = Math.floor(newConfig.collateralFactor * 4000000000); + if (newConfig.borrowFactor !== undefined) config.borrowFactor = Math.floor(newConfig.borrowFactor * 4000000000); + if (newConfig.borrowIsolated !== undefined) config.borrowIsolated = newConfig.borrowIsolated; + if (newConfig.twapWindow !== undefined) config.twapWindow = newConfig.twapWindow; + + if (newConfig.borrowFactor === 'default') newConfig.borrowFactor = 4294967295; + if (newConfig.twapWindow === 'default') newConfig.twapWindow = 16777215; + + await (await ctx.contracts.governance.connect(ctx.wallet).setAssetConfig(underlying, config)).wait(); + }; + + ctx.activateMarket = async (tok) => { + let result = await (await ctx.contracts.markets.connect(ctx.wallet).activateMarket(ctx.contracts.tokens[tok].address)).wait(); + if (process.env.GAS) console.log(`GAS(activateMarket) : ${result.gasUsed}`); + + let eTokenAddr = await ctx.contracts.markets.underlyingToEToken(ctx.contracts.tokens[tok].address); + ctx.contracts.eTokens['e' + tok] = await ethers.getContractAt('EToken', eTokenAddr); + + let dTokenAddr = await ctx.contracts.markets.eTokenToDToken(eTokenAddr); + ctx.contracts.dTokens['d' + tok] = await ethers.getContractAt('DToken', dTokenAddr); + }; + + ctx.activateMarketWithChainlinkPriceFeed = async (tok, oracleAddress) => { + let result = await (await ctx.contracts.markets.connect(ctx.wallet).activateMarketWithChainlinkPriceFeed(ctx.contracts.tokens[tok].address, oracleAddress)).wait(); + if (process.env.GAS) console.log(`GAS(activateMarketWithChainlinkPriceFeed) : ${result.gasUsed}`); + + let eTokenAddr = await ctx.contracts.markets.underlyingToEToken(ctx.contracts.tokens[tok].address); + ctx.contracts.eTokens['e' + tok] = await ethers.getContractAt('EToken', eTokenAddr); + + let dTokenAddr = await ctx.contracts.markets.eTokenToDToken(eTokenAddr); + ctx.contracts.dTokens['d' + tok] = await ethers.getContractAt('DToken', dTokenAddr); + }; + + return ctx; +} + + +main(); \ No newline at end of file diff --git a/tasks/module.js b/tasks/module.js index 00e67b79..f24eabba 100644 --- a/tasks/module.js +++ b/tasks/module.js @@ -16,9 +16,11 @@ task("module:deploy") let factory = await ethers.getContractFactory(args.module); let tx; - + if (args.module === 'RiskManager') { tx = await factory.deploy(gitCommit, ctx.tokenSetup.riskManagerSettings, await ctx.txOpts()); + } else if (args.module === 'Exec') { + tx = await factory.deploy(gitCommit, await ctx.txOpts()); } else if (args.module === 'Swap') { tx = await factory.deploy(gitCommit, ctx.tokenSetup.existingContracts.swapRouter, ctx.tokenSetup.existingContracts.oneInch, await ctx.txOpts()); } else if (args.module === 'SwapHandler1Inch') { diff --git a/tasks/testtoken.js b/tasks/testtoken.js index 10793577..d8021b61 100644 --- a/tasks/testtoken.js +++ b/tasks/testtoken.js @@ -13,8 +13,83 @@ task("testtoken:deploy") console.log(`Contract: ${result.address}`); }); -task("testtoken:mint") +task("chainlinkOracle:changeOwner") + .addPositionalParam("oracle", "address") + .addPositionalParam("newOwner", "address") + .setAction(async (args) => { + const et = require("../test/lib/eTestLib"); + const ctx = await et.getTaskCtx(); + + if (!ethers.utils.isAddress(args.oracle)) throw Error("Invalid address specified for oracle"); + if (!ethers.utils.isAddress(args.newOwner)) throw Error("Invalid address specified for new owner"); + + const oracle = await ctx.factories.MockAggregatorProxy.attach(args.oracle); + await et.taskUtils.runTx(oracle.changeOwner(args.newOwner)); + }); + +task("testtoken:activateMarket") + .addPositionalParam("token") + .setAction(async (args) => { + const et = require("../test/lib/eTestLib"); + const ctx = await et.getTaskCtx(); + + await et.taskUtils.runTx(ctx.contracts.markets.activateMarket(args.token)); + + let eTokenAddr = await ctx.contracts.markets.underlyingToEToken(args.token); + console.log(`EToken: ${eTokenAddr}`); + + let dTokenAddr = await ctx.contracts.markets.eTokenToDToken(eTokenAddr); + console.log(`DToken: ${dTokenAddr}`); + }); + +task("testtoken:activateMarketWithChainlinkPriceFeed") .addPositionalParam("token") + .addPositionalParam("oracle") + .setAction(async (args) => { + const et = require("../test/lib/eTestLib"); + const ctx = await et.getTaskCtx(); + + await et.taskUtils.runTx(ctx.contracts.markets.activateMarketWithChainlinkPriceFeed(args.token, args.oracle)); + + let eTokenAddr = await ctx.contracts.markets.underlyingToEToken(args.token); + console.log(`EToken: ${eTokenAddr}`); + + let dTokenAddr = await ctx.contracts.markets.eTokenToDToken(eTokenAddr); + console.log(`DToken: ${dTokenAddr}`); + }); + +task("testtoken:deployChainlinkOracleAndActivateMarket") + .addPositionalParam("token") + .addPositionalParam("price") + .addOptionalParam("activate") + .setAction(async (args) => { + const et = require("../test/lib/eTestLib"); + const ctx = await et.getTaskCtx(); + + const doActivate = args.activate === undefined ? false : parseBool(args.activate); + // not using lookup as the market will not have been activated + // to avoid invalid etoken address error + let tok = args.token; + let price = et.eth(args.price.toString()); + + let tx = await ctx.factories.MockAggregatorProxy.deploy(18); + console.log(`Transaction: ${tx.deployTransaction.hash}`); + + let oracle = await tx.deployed(); + console.log(`Contract: ${oracle.address}`); + + // set initial price + await et.taskUtils.runTx(oracle.mockSetValidAnswer(price)); + // activate market with chainlink price feed + // requires governance control, + // so branching/optional activation via hardhat task + if (doActivate) { + await et.taskUtils.runTx(ctx.contracts.markets.activateMarketWithChainlinkPriceFeed(tok, oracle.address)); + } + }); + +task("testtoken:mint") + .addPositionalParam("token", "symbol") .addPositionalParam("who") .addPositionalParam("amount") .setAction(async (args) => { @@ -30,7 +105,7 @@ task("testtoken:mint") }); task("testtoken:balanceOf") - .addPositionalParam("token") + .addPositionalParam("token", "symbol") .addPositionalParam("who") .setAction(async (args) => { const et = require("../test/lib/eTestLib"); @@ -43,7 +118,7 @@ task("testtoken:balanceOf") }); task("testtoken:changeOwner") - .addPositionalParam("token") + .addPositionalParam("token", "symbol") .addPositionalParam("newOwner") .setAction(async (args) => { const et = require("../test/lib/eTestLib"); @@ -53,3 +128,55 @@ task("testtoken:changeOwner") await et.taskUtils.runTx(tok.changeOwner(args.newOwner)); }); + +task("testtoken:transfer") + .addPositionalParam("token") + .addPositionalParam("who") + .addPositionalParam("amount") + .setAction(async (args) => { + const et = require("../test/lib/eTestLib"); + const ctx = await et.getTaskCtx(); + + let tok = await et.taskUtils.lookupToken(ctx, args.token); + let who = await et.taskUtils.lookupAddress(ctx, args.who); + + let decimals = await tok.decimals(); + + await et.taskUtils.runTx(tok.transfer(who, ethers.utils.parseUnits(args.amount, decimals))); + }); + +task("testtokenfaucet:setthreshold") + .addPositionalParam("token", "symbol") + .addPositionalParam("threshold", "token amount issued to testers") + .setAction(async (args) => { + const et = require("../test/lib/eTestLib"); + const ctx = await et.getTaskCtx(); + + const tok = await et.taskUtils.lookupToken(ctx, args.token); + const decimals = await tok.decimals(); + const faucet = await ethers.getContractAt("TestERC20TokenFaucet", ctx.tokenSetup.testERC20TokenFaucet); + + await et.taskUtils.runTx(faucet.setThreshold(tok.address, ethers.utils.parseUnits(args.threshold, decimals))); + }); + +task("testtokenfaucet:getthreshold") + .addPositionalParam("token", "symbol") + .setAction(async (args) => { + const et = require("../test/lib/eTestLib"); + const ctx = await et.getTaskCtx(); + + const tok = await et.taskUtils.lookupToken(ctx, args.token); + const decimals = await tok.decimals(); + const faucet = await ethers.getContractAt("TestERC20TokenFaucet", ctx.tokenSetup.testERC20TokenFaucet); + + const threshold = await faucet.getThreshold(tok.address); + console.log(`${threshold / Math.pow(10, decimals)} ${args.token}`); + }); + + +function parseBool(v) { + if (v === 'true') return true; + if (v === 'false') return false; + throw (`unexpected boolean value: ${v}`); +} + \ No newline at end of file diff --git a/tasks/zkSync.js b/tasks/zkSync.js new file mode 100644 index 00000000..0fcd4d81 --- /dev/null +++ b/tasks/zkSync.js @@ -0,0 +1,216 @@ +const zksync = require("zksync-web3"); + +task("zkSync:withdraw") + .addPositionalParam("amount", "amount as ether in decimals, e.g., 1.2") + .addOptionalParam("testnet", "boolean true if zkSync testnet operation or false if mainnet") + .setAction(async (args) => { + const testnet = args.testnet === undefined ? true : parseBool(args.testnet); + + let syncProvider = null; + let ethProvider = null; + + if (testnet) { + if (!(process.env.RPC_URL_GOERLI && process.env.RPC_URL_ZKTESTNET)) + throw '\RPC_URL_GOERLI and RPC_URL_ZKTESTNET environment variables both not found...\n'; + syncProvider = new zksync.Provider(process.env.RPC_URL_ZKTESTNET); + ethProvider = ethers.getDefaultProvider(process.env.RPC_URL_GOERLI); + } + + if (!testnet) { + if (!(process.env.RPC_URL_MAINNET && process.env.RPC_URL_ZKMAINNET)) + throw '\RPC_URL_MAINNET and RPC_URL_ZKMAINNET environment variables both not found...\n'; + syncProvider = new zksync.Provider(process.env.RPC_URL_ZKMAINNET); + ethProvider = ethers.getDefaultProvider(process.env.RPC_URL_MAINNET); + } + + const et = require("../test/lib/eTestLib"); + + const syncWallet = new zksync.Wallet(process.env.ZK_PRIVATE_KEY, syncProvider, ethProvider); + + // Retreiving the current (committed) balance of an account + const committedEthBalance = await syncWallet.getBalance(zksync.utils.ETH_ADDRESS); + if (et.formatUnits(committedEthBalance, 18) < args.amount) throw 'Insufficient balance on L2 to perform withdrawal!' + + // Retrieving the balance of an account in the last finalized block zkSync.md#confirmations-and-finality + const finalizedEthBalance = await syncWallet.getBalance(zksync.utils.ETH_ADDRESS, "finalized"); + + console.log('Committed Eth Balance', et.formatUnits(committedEthBalance, 18)); + console.log('Finalized Eth Balance', et.formatUnits(finalizedEthBalance, 18)); + + const withdrawL2 = await syncWallet.withdraw({ + token: zksync.utils.ETH_ADDRESS, + amount: et.eth(args.amount), + }); + + console.log(`Withdrawing ${args.amount} ETH from ${syncWallet.address} on zkSync L2 back to L1`); + + // Assets will be withdrawn to the target wallet + // after the validity proof of the zkSync block with this transaction is generated and verified by the mainnet contract. + // It is possible to wait until the validity proof verification is complete on L1 + // but it will take a while to finalise on L1 + // await withdrawL2.waitFinalize(); + }); + +task("zkSync:transfer") + .addPositionalParam("recipient", "An L2 zkSync wallet address") + .addPositionalParam("amount", "amount as ether in decimals, e.g., 1.2") + .addOptionalParam("testnet", "boolean true if zkSync testnet operation or false if mainnet") + .setAction(async (args) => { + const testnet = args.testnet === undefined ? true : parseBool(args.testnet); + + let syncProvider = null; + let ethProvider = null; + + if (testnet) { + if (!(process.env.RPC_URL_GOERLI && process.env.RPC_URL_ZKTESTNET)) + throw '\RPC_URL_GOERLI and RPC_URL_ZKTESTNET environment variables both not found...\n'; + syncProvider = new zksync.Provider(process.env.RPC_URL_ZKTESTNET); + ethProvider = ethers.getDefaultProvider(process.env.RPC_URL_GOERLI); + } + + if (!testnet) { + if (!(process.env.RPC_URL_MAINNET && process.env.RPC_URL_ZKMAINNET)) + throw '\RPC_URL_MAINNET and RPC_URL_ZKMAINNET environment variables both not found...\n'; + syncProvider = new zksync.Provider(process.env.RPC_URL_ZKMAINNET); + ethProvider = ethers.getDefaultProvider(process.env.RPC_URL_MAINNET); + } + + const et = require("../test/lib/eTestLib"); + + const syncWallet = new zksync.Wallet(process.env.ZK_PRIVATE_KEY, syncProvider, ethProvider); + + // Retreiving the current (committed) balance of an account + let committedEthBalance = await syncWallet.getBalance(zksync.utils.ETH_ADDRESS); + if (et.formatUnits(committedEthBalance, 18) < args.amount) throw 'Insufficient balance on L2 to perform transfer!' + + const transfer = await syncWallet.transfer({ + to: args.recipient, + token: zksync.utils.ETH_ADDRESS, + amount: et.eth(args.amount), + }); + + console.log(`Transferring ${args.amount} ETH on L2 from ${syncWallet.address} to ${args.recipient}`); + + // Await commitment + await transfer.wait(); + + // Await finalization on L1 + // await transfer.waitFinalize(); + + // // Retreiving the current (committed) balance of an account + // committedEthBalance = await syncWallet.getBalance(zksync.utils.ETH_ADDRESS); + + // Retrieving the balance of an account in the last finalized block zkSync.md#confirmations-and-finality + // const finalizedEthBalance = await syncWallet.getBalance(zksync.utils.ETH_ADDRESS, "finalized"); + + // console.log(`Wallet address: ${syncWallet.address}`); + // console.log('Committed Eth Balance', et.formatUnits(committedEthBalance, 18)); + // console.log('Finalized Eth Balance', et.formatUnits(finalizedEthBalance, 18)); + }); + +task("zkSync:deposit") + .addPositionalParam("amount", "amount as ether in decimals, e.g., 1.2") + .addOptionalParam("testnet", "boolean true if zkSync testnet operation or false if mainnet") + .setAction(async (args) => { + const testnet = args.testnet === undefined ? true : parseBool(args.testnet); + + let syncProvider = null; + let ethProvider = null; + + if (testnet) { + if (!(process.env.RPC_URL_GOERLI && process.env.RPC_URL_ZKTESTNET)) + throw '\RPC_URL_GOERLI and RPC_URL_ZKTESTNET environment variables both not found...\n'; + syncProvider = new zksync.Provider(process.env.RPC_URL_ZKTESTNET); + ethProvider = ethers.getDefaultProvider(process.env.RPC_URL_GOERLI); + } + + if (!testnet) { + if (!(process.env.RPC_URL_MAINNET && process.env.RPC_URL_ZKMAINNET)) + throw '\RPC_URL_MAINNET and RPC_URL_ZKMAINNET environment variables both not found...\n'; + syncProvider = new zksync.Provider(process.env.RPC_URL_ZKMAINNET); + ethProvider = ethers.getDefaultProvider(process.env.RPC_URL_MAINNET); + } + + const et = require("../test/lib/eTestLib"); + + const syncWallet = new zksync.Wallet(process.env.ZK_PRIVATE_KEY, syncProvider, ethProvider); + + const deposit = await syncWallet.deposit({ + token: zksync.utils.ETH_ADDRESS, + amount: et.eth(args.amount), + }); + + console.log(`Depositing ${args.amount} ETH from L1 to zkSync L2`); + + // Await processing of the deposit on L1 + const tx = await deposit.waitL1Commit(); + + // Await processing the deposit on zkSync + const result = await deposit.wait(); + + console.log(`Transaction: ${tx.transactionHash} (on ${ethProvider.network.name})`); + + console.log(`Mined. Status: ${result.status}`); + + // Retreiving the current (committed) balance of an account + const committedEthBalance = await syncWallet.getBalance(zksync.utils.ETH_ADDRESS); + + // Retrieving the balance of an account in the last finalized block zkSync.md#confirmations-and-finality + const finalizedEthBalance = await syncWallet.getBalance(zksync.utils.ETH_ADDRESS, "finalized"); + + console.log(`Wallet address: ${syncWallet.address}`); + console.log('Committed Eth Balance', et.formatUnits(committedEthBalance, 18)); + console.log('Finalized Eth Balance', et.formatUnits(finalizedEthBalance, 18)); + }); + +task("zkSync:testnetChainlinkOracleChangeOwner") + .addPositionalParam("oracle", "address") + .addPositionalParam("newOwner", "address") + .setAction(async (args) => { + const et = require("../test/lib/eTestLib"); + const ctx = await et.getTaskCtx(); + + if (!(process.env.RPC_URL_GOERLI && process.env.RPC_URL_ZKTESTNET)) + throw '\RPC_URL_GOERLI and RPC_URL_ZKTESTNET environment variables both not found...\n'; + + const syncProvider = new zksync.Provider(process.env.RPC_URL_ZKTESTNET); + const ethProvider = ethers.getDefaultProvider(process.env.RPC_URL_GOERLI); + + const syncWallet = new zksync.Wallet(process.env.ZK_PRIVATE_KEY, syncProvider, ethProvider); + + if (!ethers.utils.isAddress(args.oracle)) throw Error("Invalid address specified for oracle"); + if (!ethers.utils.isAddress(args.newOwner)) throw Error("Invalid address specified for new owner"); + + const oracle = await ctx.factories.MockAggregatorProxy.attach(args.oracle); + await et.taskUtils.runTx(oracle.connect(syncWallet).changeOwner(args.newOwner)); + }); + +task("zkSync:testnetEthBalance") + .setAction(async () => { + if (!(process.env.RPC_URL_GOERLI && process.env.RPC_URL_ZKTESTNET)) + throw '\RPC_URL_GOERLI and RPC_URL_ZKTESTNET environment variables both not found...\n'; + + const et = require("../test/lib/eTestLib"); + + const syncProvider = new zksync.Provider(process.env.RPC_URL_ZKTESTNET); + const ethProvider = ethers.getDefaultProvider(process.env.RPC_URL_GOERLI); + + const syncWallet = new zksync.Wallet(process.env.ZK_PRIVATE_KEY, syncProvider, ethProvider); + + // Retreiving the current (committed) balance of an account + const committedEthBalance = await syncWallet.getBalance(zksync.utils.ETH_ADDRESS); + + // Retrieving the balance of an account in the last finalized block zkSync.md#confirmations-and-finality + const finalizedEthBalance = await syncWallet.getBalance(zksync.utils.ETH_ADDRESS, "finalized"); + + console.log(`Wallet address: ${syncWallet.address}`); + console.log('Committed Eth Balance', et.formatUnits(committedEthBalance, 18)); + console.log('Finalized Eth Balance', et.formatUnits(finalizedEthBalance, 18)); + }); + + +function parseBool(v) { + if (v === 'true') return true; + if (v === 'false') return false; + throw (`unexpected boolean value: ${v}`); +} diff --git a/test/activateMarket.js b/test/activateMarket.js index 2a5faf63..3507b696 100644 --- a/test/activateMarket.js +++ b/test/activateMarket.js @@ -1,12 +1,16 @@ const et = require('./lib/eTestLib'); +const PRICINGTYPE__UNISWAP3_TWAP = 2 +const PRICINGTYPE__CHAINLINK = 4 +const NON_ZERO_ADDRESS = '0x0000000000000000000000000000000000000001' + et.testSet({ desc: "activating markets", }) .test({ - desc: "re-activate", + desc: "re-activate after uniswap activation", actions: ctx => [ { from: ctx.wallet, send: 'markets.activateMarket', args: [ctx.contracts.tokens.UTST.address], }, @@ -19,6 +23,36 @@ et.testSet({ { call: 'markets.underlyingToEToken', args: [ctx.contracts.tokens.UTST.address], onResult: r => { et.expect(ctx.stash.eTokenAddr).to.equal(r); }}, + + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.UTST.address, et.AddressZero], + expectError: 'e/market/underlying-already-activated' + }, + ], +}) + + +.test({ + desc: "re-activate after chainlink activation", + actions: ctx => [ + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.UTST2.address, NON_ZERO_ADDRESS], + }, + + { call: 'markets.underlyingToEToken', args: [ctx.contracts.tokens.UTST2.address], onResult: r => { + ctx.stash.eTokenAddr = r; + }}, + + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.UTST2.address, NON_ZERO_ADDRESS], + expectError: 'e/market/underlying-already-activated' + }, + + { from: ctx.wallet, send: 'markets.activateMarket', args: [ctx.contracts.tokens.UTST2.address], }, + + { call: 'markets.underlyingToEToken', args: [ctx.contracts.tokens.UTST2.address], onResult: r => { + et.expect(ctx.stash.eTokenAddr).to.equal(r); + }}, ], }) @@ -37,7 +71,22 @@ et.testSet({ .test({ desc: "no uniswap pool", actions: ctx => [ - { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST4.address], expectError: 'e/no-uniswap-pool-avail', }, + // error for permissionless activation + { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST4.address], expectError: 'e/markets/pricing-type-invalid', }, + + // succeeds for permissioned activation with Chainlink + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, NON_ZERO_ADDRESS], + }, + + { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__CHAINLINK); + et.expect(r.pricingParameters).to.equal(0); + }, }, + + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(NON_ZERO_ADDRESS); + }, }, ], }) @@ -50,6 +99,11 @@ et.testSet({ await (await ctx.contracts.uniswapPools['TST4/WETH'].mockSetThrowNotInitiated(true)).wait(); }, { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST4.address], expectError: 'e/risk/uniswap-pool-not-inited', }, + + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, NON_ZERO_ADDRESS], + expectError: 'e/risk/uniswap-pool-not-inited' + }, ], }) @@ -78,14 +132,58 @@ et.testSet({ }) +.test({ + desc: "activation with chainlink - non-governor", + actions: ctx => [ + { from: ctx.wallet2, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, et.AddressZero], + expectError: 'e/markets/unauthorized' + }, + ], +}) + + +.test({ + desc: "activation with chainlink - bad chainlink address", + actions: ctx => [ + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, et.AddressZero], + expectError: 'e/markets/bad-chainlink-address' + }, + ], +}) + + .test({ desc: "select second fee uniswap pool", actions: ctx => [ { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.LOW, }, { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST4.address], }, { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__UNISWAP3_TWAP); + et.expect(r.pricingParameters).to.equal(et.FeeAmount.LOW); + }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(et.AddressZero); + }, }, + ], +}) + + +.test({ + desc: "select second fee uniswap pool with chainlink", + actions: ctx => [ + { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.LOW, }, + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, NON_ZERO_ADDRESS], + }, + { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__CHAINLINK); et.expect(r.pricingParameters).to.equal(et.FeeAmount.LOW); }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(NON_ZERO_ADDRESS); + }, }, ], }) @@ -96,8 +194,30 @@ et.testSet({ { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.HIGH, }, { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST4.address], }, { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__UNISWAP3_TWAP); et.expect(r.pricingParameters).to.equal(et.FeeAmount.HIGH); }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(et.AddressZero); + }, }, + ], +}) + + +.test({ + desc: "select third fee uniswap pool with chainlink", + actions: ctx => [ + { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.HIGH, }, + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, NON_ZERO_ADDRESS], + }, + { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__CHAINLINK); + et.expect(r.pricingParameters).to.equal(et.FeeAmount.HIGH); + }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(NON_ZERO_ADDRESS); + }, }, ], }) @@ -117,8 +237,38 @@ et.testSet({ { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST4.address], }, { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__UNISWAP3_TWAP); + et.expect(r.pricingParameters).to.equal(et.FeeAmount.LOW); + }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(et.AddressZero); + }, }, + ], +}) + + +.test({ + desc: "choose pool with best liquidity with chainlink", + actions: ctx => [ + { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.MEDIUM, }, + { send: 'uniswapPools.TST4/WETH.mockSetLiquidity', args: [6000], }, + + { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.LOW, }, + { send: 'uniswapPools.TST4/WETH.mockSetLiquidity', args: [9000], }, + + { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.HIGH, }, + { send: 'uniswapPools.TST4/WETH.mockSetLiquidity', args: [7000], }, + + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, NON_ZERO_ADDRESS], + }, + { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__CHAINLINK); et.expect(r.pricingParameters).to.equal(et.FeeAmount.LOW); }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(NON_ZERO_ADDRESS); + }, }, ], }) @@ -134,8 +284,35 @@ et.testSet({ { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST4.address], }, { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__UNISWAP3_TWAP); et.expect(r.pricingParameters).to.equal(et.FeeAmount.HIGH); }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(et.AddressZero); + }, }, + ], +}) + + +.test({ + desc: "choose pool with best liquidity, 2, with chainlink", + actions: ctx => [ + { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.MEDIUM, }, + { send: 'uniswapPools.TST4/WETH.mockSetLiquidity', args: [6000], }, + + { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.HIGH, }, + { send: 'uniswapPools.TST4/WETH.mockSetLiquidity', args: [7000], }, + + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, NON_ZERO_ADDRESS], + }, + { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__CHAINLINK); + et.expect(r.pricingParameters).to.equal(et.FeeAmount.HIGH); + }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(NON_ZERO_ADDRESS); + }, }, ], }) @@ -151,8 +328,35 @@ et.testSet({ { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST4.address], }, { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__UNISWAP3_TWAP); et.expect(r.pricingParameters).to.equal(et.FeeAmount.MEDIUM); }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(et.AddressZero); + }, }, + ], +}) + + +.test({ + desc: "choose pool with best liquidity, 3, with chainlink", + actions: ctx => [ + { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.MEDIUM, }, + { send: 'uniswapPools.TST4/WETH.mockSetLiquidity', args: [7000], }, + + { action: 'createUniswapPool', pair: 'TST4/WETH', fee: et.FeeAmount.HIGH, }, + { send: 'uniswapPools.TST4/WETH.mockSetLiquidity', args: [6000], }, + + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, NON_ZERO_ADDRESS], + }, + { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__CHAINLINK); + et.expect(r.pricingParameters).to.equal(et.FeeAmount.MEDIUM); + }, }, + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST4.address], onResult: r => { + et.expect(r).to.equal(NON_ZERO_ADDRESS); + }, }, ], }) @@ -172,6 +376,11 @@ et.testSet({ }, }, { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST4.address], expectError: 'e/bad-uniswap-pool-addr'}, + + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST4.address, NON_ZERO_ADDRESS], + expectError: 'e/bad-uniswap-pool-addr', + }, ], }) diff --git a/test/activateMarketNoUniswap.js b/test/activateMarketNoUniswap.js new file mode 100644 index 00000000..c85c475e --- /dev/null +++ b/test/activateMarketNoUniswap.js @@ -0,0 +1,92 @@ +const et = require('./lib/eTestLib'); + +const PRICINGTYPE__CHAINLINK = 4 +const NON_ZERO_ADDRESS = '0x0000000000000000000000000000000000000001' + +et.testSet({ + desc: "activating markets without uniswap", + fixture: 'testing-no-uniswap' +}) + + +.test({ + desc: "re-activate", + actions: ctx => [ + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.WETH.address, NON_ZERO_ADDRESS], + }, + + { call: 'markets.underlyingToEToken', args: [ctx.contracts.tokens.WETH.address], onResult: r => { + ctx.stash.eTokenAddr = r; + }}, + + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.WETH.address, NON_ZERO_ADDRESS], + expectError: 'e/market/underlying-already-activated' + }, + + { from: ctx.wallet, send: 'markets.activateMarket', args: [ctx.contracts.tokens.WETH.address], }, + + { call: 'markets.underlyingToEToken', args: [ctx.contracts.tokens.WETH.address], onResult: r => { + et.expect(ctx.stash.eTokenAddr).to.equal(r); + }}, + ], +}) + + +.test({ + desc: "invalid contracts", + actions: ctx => [ + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.euler.address, NON_ZERO_ADDRESS], + expectError: 'e/markets/invalid-token', + }, + + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.WETH.address, NON_ZERO_ADDRESS], + }, + { action: 'cb', cb: async () => { + const eWETH = await ctx.contracts.markets.underlyingToEToken(ctx.contracts.tokens.WETH.address); + const dWETH = await ctx.contracts.markets.underlyingToDToken(ctx.contracts.tokens.WETH.address); + + let msg; + await ctx.contracts.markets.activateMarketWithChainlinkPriceFeed(eWETH, NON_ZERO_ADDRESS) + .catch(e => { + msg = e.message; + }); + et.expect(msg).to.contains('e/markets/invalid-token'); + + msg = "" + await ctx.contracts.markets.activateMarketWithChainlinkPriceFeed(dWETH, NON_ZERO_ADDRESS) + .catch(e => { + msg = e.message; + }); + et.expect(msg).to.contains('e/markets/invalid-token'); + } }, + ], +}) + + +.test({ + desc: "no uniswap factory", + actions: ctx => [ + // error for permissionless activation + { send: 'markets.activateMarket', args: [ctx.contracts.tokens.TST.address], expectError: 'e/markets/pricing-type-invalid', }, + + // succeeds for permissioned activation with Chainlink + { from: ctx.wallet, send: 'markets.activateMarketWithChainlinkPriceFeed', + args: [ctx.contracts.tokens.TST.address, NON_ZERO_ADDRESS], + }, + + { call: 'markets.getPricingConfig', args: [ctx.contracts.tokens.TST.address], onResult: r => { + et.expect(r.pricingType).to.equal(PRICINGTYPE__CHAINLINK); + et.expect(r.pricingParameters).to.equal(0); + }, }, + + { call: 'markets.getChainlinkPriceFeedConfig', args: [ctx.contracts.tokens.TST.address], onResult: r => { + et.expect(r).to.equal(NON_ZERO_ADDRESS); + }, }, + ], +}) + +.run(); diff --git a/test/batch.js b/test/batch.js index c371f645..16cca55e 100644 --- a/test/batch.js +++ b/test/batch.js @@ -232,6 +232,26 @@ et.testSet({ ] }) +.test({ + desc: "new batch simulate", + actions: ctx => [ + { send: 'eTokens.eTST.deposit', args: [0, et.eth(1)], }, + { send: 'tokens.TST.configure', args: ['transfer/revert', []] }, + { action: 'sendBatch', simulate: true, deferLiquidityChecks: [ctx.wallet.address], batch: [ + { send: 'eTokens.eTST.withdraw', args: [0, et.eth(1)], }, + ], onResult: r => { + et.expect(r[0].success).to.equal(false); + // safeTransferFrom adds additional error bytes that we need to remove + // first 4 bytes are the error selector + // second 32 bytes are the pointer for the start of error msg + // third 32 bytes are the length of the error msg + // then we have 4 bytes of again the Error(string) selector = 08c379a0 + // size = 4 + 32 + 32 + 4 = 72 which equals 144 length slice + 2 for 0x = 146 + const msg = utils.defaultAbiCoder.decode(["string"], "0x" + r[0].result.slice(146))[0]; + et.expect(msg).to.equal("revert behaviour") + }}, + ] +}) .run(); diff --git a/test/chainlinkPriceFeed.js b/test/chainlinkPriceFeed.js index 46bbada4..a3083bd0 100644 --- a/test/chainlinkPriceFeed.js +++ b/test/chainlinkPriceFeed.js @@ -14,6 +14,71 @@ et.testSet({ ] }) +.test({ + desc: "set the correct owner upon deployment", + actions: ctx => [ + { call: 'AggregatorTST.owner', args: [], assertEql: ctx.wallet.address, }, + ] +}) + +.test({ + desc: "reverts if non-owner attempts to set price via mockSetValidAnswer", + actions: ctx => [ + { call: 'AggregatorTST.latestAnswer', args: [], assertEql: 0, }, + + { from: ctx.wallet2, send: 'AggregatorTST.mockSetValidAnswer', args: [et.eth('1')], + expectError: 'unauthorized', + }, + + { call: 'AggregatorTST.latestAnswer', args: [], assertEql: 0, }, + + { from: ctx.wallet, send: 'AggregatorTST.mockSetValidAnswer', args: [et.eth('1')], }, + + { call: 'AggregatorTST.latestAnswer', args: [], assertEql: et.eth('1'), }, + ] +}) + +.test({ + desc: "reverts if non-owner attempts to set price via mockSetData", + actions: ctx => [ + { action: 'cb', cb: async () => { + let latestAnswer = await ctx.contracts.AggregatorTST.latestAnswer(); + et.expect(latestAnswer).to.equal(0); + + let errMsg = ''; + try { + await ctx.contracts.AggregatorTST.connect(ctx.wallet2).mockSetData([1, 123456, 0, 0, 0]); + latestAnswer = await ctx.contracts.AggregatorTST.latestAnswer(); + et.expect(latestAnswer).to.equal(0); + + await ctx.contracts.AggregatorTST.connect(ctx.wallet).mockSetData([1, 123456, 0, 0, 0]); + latestAnswer = await ctx.contracts.AggregatorTST.latestAnswer(); + et.expect(latestAnswer).to.equal(123456); + } catch (e) { + errMsg = e.message; + } + et.expect(errMsg).to.contains('unauthorized'); + }}, + ] +}) + +.test({ + desc: "reverts if non-owner attempts to change owner", + actions: ctx => [ + { call: 'AggregatorTST.owner', args: [], assertEql: ctx.wallet.address, }, + + { from: ctx.wallet2, send: 'AggregatorTST.changeOwner', args: [ctx.wallet2.address], + expectError: 'unauthorized', + }, + + { call: 'AggregatorTST.owner', args: [], assertEql: ctx.wallet.address, }, + + { from: ctx.wallet, send: 'AggregatorTST.changeOwner', args: [ctx.wallet2.address], }, + + { call: 'AggregatorTST.owner', args: [], assertEql: ctx.wallet2.address, }, + ] +}) + .test({ desc: "chainlink pricing setup and price fetch", actions: ctx => [ @@ -216,4 +281,87 @@ et.testSet({ ], }) +.test({ + desc: "chainlink price scaling when USD is the reference asset", + actions: ctx => [ + { action: 'cb', cb: async () => { + + // Install RiskManager with the USD as the reference asset + const riskManagerSettings = { + referenceAsset: et.ethers.utils.hexZeroPad(et.BN(840).toHexString(), 20), + uniswapFactory: ethers.constants.AddressZero, + uniswapPoolInitCodeHash: et.ethers.utils.hexZeroPad('0x', 32), + } + + ctx.contracts.modules.riskManager = await (await ctx.factories.RiskManager.deploy( + et.ethers.utils.hexZeroPad('0x', 32), + riskManagerSettings + )).deployed() + + await (await ctx.contracts.installer.connect(ctx.wallet) + .installModules([ctx.contracts.modules.riskManager.address])).wait(); + }}, + + // Set up the price feed + + { send: 'governance.setChainlinkPriceFeed', args: + [ctx.contracts.tokens.TST.address, ctx.contracts.AggregatorTST.address], onLogs: logs => { + et.expect(logs.length).to.equal(1); + et.expect(logs[0].name).to.equal('GovSetChainlinkPriceFeed'); + et.expect(logs[0].args.underlying).to.equal(ctx.contracts.tokens.TST.address); + et.expect(logs[0].args.chainlinkAggregator).to.equal(ctx.contracts.AggregatorTST.address); + }}, + + // Set pool pricing configuration + + { send: 'governance.setPricingConfig', args: [ctx.contracts.tokens.TST.address, PRICINGTYPE__CHAINLINK, et.DefaultUniswapFee], onLogs: logs => { + et.expect(logs.length).to.equal(1); + et.expect(logs[0].name).to.equal('GovSetPricingConfig'); + et.expect(logs[0].args.underlying).to.equal(ctx.contracts.tokens.TST.address); + et.expect(logs[0].args.newPricingType).to.equal(PRICINGTYPE__CHAINLINK); + et.expect(logs[0].args.newPricingParameter).to.equal(et.DefaultUniswapFee); + }}, + + // test getPrice + + { action: 'cb', cb: async () => { + await ctx.contracts.AggregatorTST.mockSetData([1, et.ethers.utils.parseUnits('1', 8), 0, 0, 0]); + const resultTST = await ctx.contracts.exec.getPrice(ctx.contracts.tokens.TST.address); + et.expect(resultTST.twap).to.equal(et.ethers.utils.parseUnits('1', 18)); + et.expect(resultTST.twapPeriod).to.equal(0); + }}, + + // test getPriceFull + + { action: 'cb', cb: async () => { + // Set up the price equal to the max price of 1e36 + + await ctx.contracts.AggregatorTST.mockSetData([1, et.ethers.utils.parseUnits('1', 8), 0, 0, 0]); + const resultTST = await ctx.contracts.exec.getPriceFull(ctx.contracts.tokens.TST.address); + et.expect(resultTST.twap).to.equal(et.ethers.utils.parseUnits('1', 18)); + et.expect(resultTST.currPrice).to.equal(resultTST.twap); + et.expect(resultTST.twapPeriod).to.equal(0); + }}, + + // test getPrice + + { action: 'cb', cb: async () => { + await ctx.contracts.AggregatorTST.mockSetData([1, et.ethers.utils.parseUnits('1.2345', 8), 0, 0, 0]); + const resultTST = await ctx.contracts.exec.getPrice(ctx.contracts.tokens.TST.address); + et.expect(resultTST.twap).to.equal(et.ethers.utils.parseUnits('1.2345', 18)); + et.expect(resultTST.twapPeriod).to.equal(0); + }}, + + // test getPriceFull + + { action: 'cb', cb: async () => { + await ctx.contracts.AggregatorTST.mockSetData([1, et.ethers.utils.parseUnits('1.2345', 8), 0, 0, 0]); + const resultTST = await ctx.contracts.exec.getPriceFull(ctx.contracts.tokens.TST.address); + et.expect(resultTST.twap).to.equal(et.ethers.utils.parseUnits('1.2345', 18)); + et.expect(resultTST.currPrice).to.equal(resultTST.twap); + et.expect(resultTST.twapPeriod).to.equal(0); + }} + ], +}) + .run(); diff --git a/test/decimalsAbove18.js b/test/decimalsAbove18.js index 8ce649d4..56f2f49b 100644 --- a/test/decimalsAbove18.js +++ b/test/decimalsAbove18.js @@ -8,7 +8,7 @@ et.testSet({ .test({ desc: "names, symbols and decimals", actions: ctx => [ - { call: 'tokens.UTST.name', args: [], assertEql: 'Unactivated Test Token', }, + { call: 'tokens.UTST.name', args: [], assertEql: 'Unactivated Test Token 1', }, { call: 'tokens.UTST.symbol', args: [], assertEql: 'UTST', }, { call: 'tokens.UTST.decimals', args: [], equals: [18], }, @@ -45,4 +45,4 @@ et.testSet({ }) -.run(); \ No newline at end of file +.run(); diff --git a/test/lib/deployLib.js b/test/lib/deployLib.js index ea061812..a30fee26 100644 --- a/test/lib/deployLib.js +++ b/test/lib/deployLib.js @@ -1,31 +1,58 @@ +async function verifyContract(contractAddress, contractArgs, contractPath = null) { + try { + if (contractPath) { + await run("verify:verify", { + address: contractAddress, + constructorArguments: [...contractArgs], + contract: contractPath + }); + } else { + await run("verify:verify", { + address: contractAddress, + constructorArguments: [...contractArgs], + }); + } + + } catch (error) { + console.log(`Smart contract verification for contract at ${contractAddress}, was not successful\n ${error.message}`); + } +} + async function verifyBatch(verification) { - if (Object.keys(verification.contracts.tokens).length > 0) { - console.log("Verifying test tokens"); + console.log("\nVerifying test tokens"); for (let token of Object.keys(verification.contracts.tokens)) { console.log(token, verification.contracts.tokens[token].address, verification.contracts.tokens[token].args, verification.contracts.tokens[token].contractPath); await verifyContract(verification.contracts.tokens[token].address, verification.contracts.tokens[token].args, verification.contracts.tokens[token].contractPath); } } - + if (Object.keys(verification.contracts.modules).length > 0) { - console.log("Verifying modules"); + console.log("\nVerifying modules"); for (let module of Object.keys(verification.contracts.modules)) { console.log(module, verification.contracts.modules[module].address, verification.contracts.modules[module].args, verification.contracts.modules[module].contractPath); await verifyContract(verification.contracts.modules[module].address, verification.contracts.modules[module].args, verification.contracts.modules[module].contractPath); } } - + if (Object.keys(verification.contracts.swapHandlers).length > 0) { - console.log("Verifying swap handlers"); + console.log("\nVerifying swap handlers"); for (let handler of Object.keys(verification.contracts.swapHandlers)) { console.log(handler, verification.contracts.swapHandlers[handler].address, verification.contracts.swapHandlers[handler].args, verification.contracts.swapHandlers[handler].contractPath); await verifyContract(verification.contracts.swapHandlers[handler].address, verification.contracts.swapHandlers[handler].args, verification.contracts.swapHandlers[handler].contractPath); } } + + if (Object.keys(verification.contracts.oracles).length > 0) { + console.log("\nVerifying ERC-20 token price oracles"); + for (let oracle of Object.keys(verification.contracts.oracles)) { + console.log(oracle, verification.contracts.oracles[oracle].address, verification.contracts.oracles[oracle].args, verification.contracts.oracles[oracle].contractPath); + await verifyContract(verification.contracts.oracles[oracle].address, verification.contracts.oracles[oracle].args, verification.contracts.oracles[oracle].contractPath); + } + } if (Object.keys(verification.contracts).length > 0) { - console.log("Verifying euler contracts"); + console.log("\nVerifying euler contracts"); for (let contract of Object.keys(verification.contracts)) { if (verification.contracts[contract].address && verification.contracts[contract].args) { console.log(contract, verification.contracts[contract].address, verification.contracts[contract].args, verification.contracts[contract].contractPath); @@ -33,30 +60,9 @@ async function verifyBatch(verification) { } } } - -} - -async function verifyContract(contractAddress, contractArgs, contractPath = null) { - try { - if (contractPath) { - await run("verify:verify", { - address: contractAddress, - constructorArguments: [...contractArgs], - contract: contractPath - }); - } else { - await run("verify:verify", { - address: contractAddress, - constructorArguments: [...contractArgs], - }); - } - - } catch (error) { - console.log(`Smart contract verification for contract at ${contractAddress}, was not successful\n ${error.message}`); - } } module.exports = { verifyBatch, - verifyContract + verifyContract, } diff --git a/test/lib/eTestLib.js b/test/lib/eTestLib.js index 4c90ae81..ab4d50b4 100644 --- a/test/lib/eTestLib.js +++ b/test/lib/eTestLib.js @@ -88,6 +88,7 @@ const contractNames = [ // Testing 'TestERC20', + 'TestERC20TokenFaucet', 'MockUniswapV3Factory', 'EulerGeneralView', 'InvariantChecker', @@ -107,6 +108,7 @@ const contractNames = [ // View 'EulerSimpleLens', + 'DeltaBalances', ]; @@ -146,6 +148,7 @@ async function buildContext(provider, wallets, tokenSetupName) { contracts: { tokens: {}, + oracles: {}, eTokens: {}, dTokens: {}, uniswapPools: {}, @@ -172,6 +175,17 @@ async function buildContext(provider, wallets, tokenSetupName) { ctx.contracts.dTokens['d' + tok] = await ethers.getContractAt('DToken', dTokenAddr); }; + ctx.activateMarketWithChainlinkPriceFeed = async (tok, oracleAddress) => { + let result = await (await ctx.contracts.markets.activateMarketWithChainlinkPriceFeed(ctx.contracts.tokens[tok].address, oracleAddress)).wait(); + if (process.env.GAS) console.log(`GAS(activateMarketWithChainlinkPriceFeed) : ${result.gasUsed}`); + + let eTokenAddr = await ctx.contracts.markets.underlyingToEToken(ctx.contracts.tokens[tok].address); + ctx.contracts.eTokens['e' + tok] = await ethers.getContractAt('EToken', eTokenAddr); + + let dTokenAddr = await ctx.contracts.markets.eTokenToDToken(eTokenAddr); + ctx.contracts.dTokens['d' + tok] = await ethers.getContractAt('DToken', dTokenAddr); + }; + ctx.populateUniswapPool = async (pair, fee) => { const addr = await ctx.contracts.uniswapV3Factory.getPool(ctx.contracts.tokens[pair[0]].address, ctx.contracts.tokens[pair[1]].address, fee); @@ -679,6 +693,7 @@ function exportAddressManifest(ctx) { let output = { tokens: {}, modules: {}, + chainlinkCompatOracles: {}, swapHandlers: {}, }; @@ -698,6 +713,10 @@ function exportAddressManifest(ctx) { output.swapHandlers[swapHandlerName] = ctx.contracts.swapHandlers[swapHandlerName].address; } + for (let tok of Object.keys(ctx.contracts.oracles)) { + output.chainlinkCompatOracles[tok] = ctx.contracts.oracles[tok].address; + } + if (ctx.tokenSetup.testing && ctx.tokenSetup.testing.useRealUniswap) { output.swapRouterV3.address = ctx.contracts.swapRouterV3.address; output.swapRouter02.address = ctx.contracts.swapRouter02.address; @@ -718,21 +737,30 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) let verification = { contracts: { tokens: {}, + oracles: {}, modules: {}, swapHandlers: {} }, }; - if (verify === "true" && ["goerli"].includes(hre.network.name)) { + if (verify === "true" && ["goerli", "mainnet"].includes(hre.network.name)) { if (!process.env.ETHERSCAN_API_KEY) { throw Error("Required process.env.ETHERSCAN_API_KEY variable not found."); } - } else if (verify === "true" && ["mumbai"].includes(hre.network.name)) { + } else if (verify === "true" && ["polygonmumbai", "polygon"].includes(hre.network.name)) { if (!process.env.POLYGONSCAN_API_KEY) { throw Error("Required process.env.POLYGONSCAN_API_KEY variable not found."); } - } else if (verify === "true" && !["goerli", "mumbai"].includes(hre.network.name)) { - throw Error(`Cannot verify contracts on ${hre.network.name}`); + } else if (verify === "true" && ["optimismgoerli", "optimismmainnet"].includes(hre.network.name)) { + if (!process.env.OPTIMISMSCAN_API_KEY) { + throw Error("Required process.env.OPTIMISMSCAN_API_KEY variable not found."); + } + } else if (verify === "true" && ["bsctestnet", "bsc"].includes(hre.network.name)) { + if (!process.env.BSCSCAN_API_KEY) { + throw Error("Required process.env.BSCSCAN_API_KEY variable not found."); + } + } else if (verify === "true" && !["goerli", "mainnet", "polygonmumbai", "polygon", "bsctestnet", "bsc"].includes(hre.network.name)) { + throw Error(`Cannot verify contracts programmatically on ${hre.network.name}`); } let ctx = await buildContext(provider, wallets, tokenSetupName); @@ -753,6 +781,15 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) verification.contracts.tokens[token.symbol] = { address: ctx.contracts.tokens[token.symbol].address, args: [token.name, token.symbol, token.decimals, false], contractPath: "contracts/test/TestERC20.sol:TestERC20" }; + + // if price oracle is chainlink, deploy oracle + if (ctx.tokenSetup.testing.chainlinkOracles && ctx.tokenSetup.testing.chainlinkOracles.includes(token.symbol)) { + ctx.contracts.oracles[token.symbol] = await (await ctx.factories.MockAggregatorProxy.deploy(18)).deployed(); + verification.contracts.oracles[token.symbol] = { + address: ctx.contracts.oracles[token.symbol].address, args: [18], contractPath: "contracts/test/MockEACAggregatorProxy.sol:MockAggregatorProxy" + }; + } + } for (let [symbol, { address }] of Object.entries(ctx.tokenSetup.testing.forkTokens || {})) { @@ -812,7 +849,7 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) ctx.uniswapV3PoolByteCodeHash = ethers.utils.keccak256((await ethers.getContractFactory('MockUniswapV3Pool')).bytecode); } - + ctx.contracts.invariantChecker = await (await ctx.factories.InvariantChecker.deploy()).deployed(); verification.contracts.invariantChecker = { address: ctx.contracts.invariantChecker.address, args: [], contractPath: "contracts/test/InvariantChecker.sol:InvariantChecker" @@ -861,7 +898,6 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) } } - // Euler Contracts // Create module implementations @@ -870,6 +906,16 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) if (ctx.tokenSetup.riskManagerSettings) { riskManagerSettings = ctx.tokenSetup.riskManagerSettings; + + // Deployment without Uniswap (Factory) + if (riskManagerSettings.uniswapFactory === module.exports.AddressZero) { + riskManagerSettings.uniswapFactory = riskManagerSettings.uniswapFactory; + riskManagerSettings.uniswapPoolInitCodeHash = module.exports.HashZero; + } + + if (!riskManagerSettings.referenceAsset) { + riskManagerSettings.referenceAsset = ctx.contracts.tokens['WETH'].address; + } } else { riskManagerSettings = { referenceAsset: ctx.contracts.tokens['WETH'].address, @@ -894,7 +940,7 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) verification.contracts.modules.markets = { address: ctx.contracts.modules.markets.address, args: [gitCommit], contractPath: "contracts/modules/Markets.sol:Markets" }; - + ctx.contracts.modules.liquidation = await (await ctx.factories.Liquidation.deploy(gitCommit)).deployed(); verification.contracts.modules.liquidation = { address: ctx.contracts.modules.liquidation.address, args: [gitCommit], contractPath: "contracts/modules/Liquidation.sol:Liquidation" @@ -907,7 +953,7 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) ctx.contracts.modules.exec = await (await ctx.factories.Exec.deploy(gitCommit)).deployed(); verification.contracts.modules.exec = { - address: ctx.contracts.modules.exec.address, args: [gitCommit], contractPath: "contracts/modules/Exex.sol:Exec" + address: ctx.contracts.modules.exec.address, args: [gitCommit], contractPath: "contracts/modules/Exec.sol:Exec" }; ctx.contracts.modules.swap = await (await ctx.factories.Swap.deploy(gitCommit, swapRouterV3Address, oneInchAddress)).deployed(); @@ -979,6 +1025,11 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) address: ctx.contracts.eulerSimpleLens.address, args: [gitCommit, ctx.contracts.euler.address], contractPath: "contracts/views/EulerSimpleLens.sol:EulerSimpleLens" }; + ctx.contracts.deltaBalances = await (await ctx.factories.DeltaBalances.deploy()).deployed(); + verification.contracts.deltaBalances = { + address: ctx.contracts.deltaBalances.address, args: [], contractPath: "contracts/views/DeltaBalances.sol:DeltaBalances" + }; + ctx.contracts.eulerGeneralView = await (await ctx.factories.EulerGeneralView.deploy(gitCommit)).deployed(); verification.contracts.eulerGeneralView = { address: ctx.contracts.eulerGeneralView.address, args: [gitCommit], contractPath: "contracts/views/EulerGeneralView.sol:EulerGeneralView" @@ -1055,9 +1106,18 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) // Setup default ETokens/DTokens for (let tok of ctx.tokenSetup.testing.activated) { - await ctx.activateMarket(tok); + if (ctx.tokenSetup.testing.chainlinkOracles && ctx.tokenSetup.testing.chainlinkOracles.includes(tok)) { + let et = module.exports; + await ctx.activateMarketWithChainlinkPriceFeed(tok, ctx.contracts.oracles[tok].address); + if (ctx.tokenSetup.testing.chainlinkPrices[tok]) { + await ctx.contracts.oracles[tok].mockSetValidAnswer(et.eth(ctx.tokenSetup.testing.chainlinkPrices[tok].toString())); + } + } else { + await ctx.activateMarket(tok); + } } + for (let tok of (ctx.tokenSetup.testing.tokens || [])) { if (tok.config) { if (!ctx.tokenSetup.testing.activated.find(s => s === tok.symbol)) throw(`can't set config for unactivated asset: ${tok.symbol}`); @@ -1084,6 +1144,16 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) }; + // Setup test ERC-20 token faucet + ctx.contracts.testERC20TokenFaucet = await (await ctx.factories.TestERC20TokenFaucet.deploy( + )).deployed(); + verification.contracts.testERC20TokenFaucet = { + address: ctx.contracts.testERC20TokenFaucet.address, + args: [], + contractPath: "contracts/test/TestERC20TokenFaucet.sol:TestERC20TokenFaucet" + }; + + // Setup liquidity mining contracts if (ctx.contracts.tokens.EUL) { @@ -1103,7 +1173,7 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) ctx.contracts.eulStakes.address, )).deployed(); verification.contracts.eulDistributor = { - address: ctx.contracts.eulStakes.address, + address: ctx.contracts.eulDistributor.address, args: [ ctx.contracts.tokens.EUL.address, ctx.contracts.eulStakes.address @@ -1112,11 +1182,12 @@ async function deployContracts(provider, wallets, tokenSetupName, verify = null) }; } - if (verify === "true") { - let outputJson = JSON.stringify(verification, ' ', 4); - fs.writeFileSync(`./euler-contracts-verification-${tokenSetupName}.json`, outputJson + "\n"); + let outputJson = JSON.stringify(verification, ' ', 4); + fs.writeFileSync(`./euler-contracts-verification-${tokenSetupName}.json`, outputJson + "\n"); - // wait 30 seconds for etherscan/polygonscan to index/store contract code + if (verify === "true") { + // wait 30 seconds for explorer, e.g., + // etherscan/polygonscan to index/store deployed contract code await sleep(30000); console.log("\n Verifying smart contracts...\n"); @@ -1455,12 +1526,7 @@ class TestSet { let result; if (action.simulate) { - try { - await ctx.contracts.exec.connect(from).callStatic.batchDispatchSimulate(items, action.deferLiquidityChecks || []); - } catch (e) { - if (e.errorName !== 'BatchDispatchSimulation') throw e; - result = e.errorArgs.simulation; - } + result = await ctx.contracts.exec.connect(from).callStatic.batchDispatchSimulateDecoded(items, action.deferLiquidityChecks || []); } else { let tx = await ctx.contracts.exec.connect(from).batchDispatch(items, action.deferLiquidityChecks || []); result = await tx.wait(); @@ -1731,6 +1797,7 @@ module.exports = { // tasks taskUtils, moduleIds, - + contractNames, + config, }; diff --git a/test/lib/token-setups/basetestnet.js b/test/lib/token-setups/basetestnet.js new file mode 100644 index 00000000..57e6e096 --- /dev/null +++ b/test/lib/token-setups/basetestnet.js @@ -0,0 +1,29 @@ +module.exports = { + riskManagerSettings: { + referenceAsset: '0xE392Ee380A9917D08B521E9488a66C83364678d2', // WETH ref asset + uniswapFactory: '0x0000000000000000000000000000000000000000', + uniswapPoolInitCodeHash: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + + existingContracts: { + eulToken: "0x6ad40cE1C9D3A518dCE8D89295008ECA1bf0F321" + }, + + existingTokens: { + WETH: { + address: "0xE392Ee380A9917D08B521E9488a66C83364678d2" + }, + EUL: { + address: "0x6ad40cE1C9D3A518dCE8D89295008ECA1bf0F321" + }, + USDC: { + address: "0xe727D925Ab233273d87fAb6Da58446Ed610CEdC7" + }, + COMP: { + address: "0xCAF841C852132f32738eecbd0b4f5d482e16b262" + }, + WBTC: { + address: "0x5171Be04CdBF5e958a947f7CFED4cAb0EE0D329d" + } + }, +} \ No newline at end of file diff --git a/test/lib/token-setups/bsctestnet.js b/test/lib/token-setups/bsctestnet.js new file mode 100644 index 00000000..4ad52f98 --- /dev/null +++ b/test/lib/token-setups/bsctestnet.js @@ -0,0 +1,32 @@ +module.exports = { + riskManagerSettings: { + referenceAsset: '0x0000000000000000000000000000000000000348', // address(840) USDC ref asset + uniswapFactory: '0x0000000000000000000000000000000000000000', + uniswapPoolInitCodeHash: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + + existingContracts: { + eulToken: "0x427Dc179e9Aabbf890322c88B5b7eCB449D7a224" + }, + + existingTokens: { + WETH: { + address: "0x594a6993bB7A533132D65001a7C99fC66Fae38F4" + }, + EUL: { + address: "0x427Dc179e9Aabbf890322c88B5b7eCB449D7a224" + }, + USDT: { + address: "0x69632F2DB366e9Af8fdb767F674B0F0e4Da812C6" + }, + USDC: { + address: "0x8682B60F3dBaa29343D60c94D26CacdC0469Ed72" + }, + COMP: { + address: "0x3BBC61d81035eD583fFb675d230eECb30D934Fde" + }, + WBTC: { + address: "0x2d5C5c1be18a9B17A15D82575d895eC14B3d3549" + } + }, +} \ No newline at end of file diff --git a/test/lib/token-setups/optimismgoerli.js b/test/lib/token-setups/optimismgoerli.js new file mode 100644 index 00000000..20fb2007 --- /dev/null +++ b/test/lib/token-setups/optimismgoerli.js @@ -0,0 +1,48 @@ +module.exports = { + riskManagerSettings: { + referenceAsset: '0x830e930B18C795192ac20e680bcDd3ce0984B4fB', + uniswapFactory: '0x0000000000000000000000000000000000000000', + uniswapPoolInitCodeHash: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + + testERC20TokenFaucet: "0x7A9921787a89A49c828667CaA7BBE48010B65D33", + + existingTokens: { + EUL: { + address: "0x598419fB7cD8829E7471aFe1aFd5c2b35c9A82BC", + }, + WETH: { + address: "0x830e930B18C795192ac20e680bcDd3ce0984B4fB", + }, + DAI: { + address: "0x3189e190202050ae3E54f49bBD79569Ab48FF0dF", + }, + BZRX: { + address: "0x87d71e333F01b6C6786a2374bc776FcdF8960103", + }, + CRV: { + address: "0xc847F5f8de257D48B3c55CB868187381F6B441aA", + }, + DOUGH: { + address: "0x2815C34e27af8Cf632049De1693FbAA0FA10F307", + }, + REP: { + address: "0xfa8FABB91200A381fC74433B3aC3B8A6BF9eA3d0", + }, + UNI: { + address: "0x7FbE772506080fE1261d2Df2d7dA839Ec4Dfac99", + }, + USDT: { + address: "0x3d96928242D0585B45b1218f671875E209081fdd", + }, + USDC: { + address: "0x90E644678b43399659010DD07259ED61E372ddb5", + }, + WBTC: { + address: "0x1231343C8595FC2Da9C16F871e000fa69B68b9b8", + }, + COMP: { + address: "0xCb8Ca7100Cf883769364BAd2324E710E8C17c96f", + }, + }, +} \ No newline at end of file diff --git a/test/lib/token-setups/testing-chainlink-no-uni-deploy.js b/test/lib/token-setups/testing-chainlink-no-uni-deploy.js new file mode 100644 index 00000000..7c63ee64 --- /dev/null +++ b/test/lib/token-setups/testing-chainlink-no-uni-deploy.js @@ -0,0 +1,102 @@ +module.exports = { + riskManagerSettings: { + referenceAsset: '0x0000000000000000000000000000000000000001', + uniswapFactory: '0x0000000000000000000000000000000000000000', + }, + + testing: { + tokens: [ + { + name: "Euler", + symbol: "EUL", + decimals: 18, + config: { + collateralFactor: 0, + borrowFactor: 0.25, + borrowIsolated: true, + }, + }, + { + name: "Wrapped ETH", + symbol: "WETH", + decimals: 18, + config: { + collateralFactor: 0.85, + borrowFactor: 0.8, + borrowIsolated: false, + }, + }, + { + name: "Tether USD", + symbol: "USDT", + decimals: 6, + config: { + collateralFactor: 0.9, + borrowFactor: 0.94, + borrowIsolated: false, + }, + }, + { + name: "USD Coin", + symbol: "USDC", + decimals: 6, + config: { + collateralFactor: 0.9, + borrowFactor: 0.94, + borrowIsolated: false, + }, + }, + { + name: "Compound", + symbol: "COMP", + decimals: 18, + config: { + collateralFactor: 0, + borrowFactor: 0.7, + borrowIsolated: true, + }, + }, + { + name: "Wrapped BTC", + symbol: "WBTC", + decimals: 8, + config: { + collateralFactor: 0.88, + borrowFactor: 0.91, + borrowIsolated: false, + }, + }, + ], + + uniswapPools: [ + // ["USDC", "WETH"], + ], + + activated: [ + "WETH", + "EUL", + "USDT", + "USDC", + "COMP", + "WBTC", + ], + + chainlinkOracles: [ + "WETH", + "EUL", + "USDT", + "USDC", + "COMP", + "WBTC", + ], + + chainlinkPrices: { + WETH: 1, + EUL: 0.0031974695, + USDT: 0.00062015328626584, + USDC: 0.00061877505779954, + COMP: 0.031852903127343, + WBTC: 14.28179057601, + }, + }, +}; \ No newline at end of file diff --git a/test/lib/token-setups/testing-small.js b/test/lib/token-setups/testing-small.js new file mode 100644 index 00000000..6380b5b3 --- /dev/null +++ b/test/lib/token-setups/testing-small.js @@ -0,0 +1,162 @@ +module.exports = { + riskManagerSettings: { + uniswapFactory: '0x0000000000000000000000000000000000000000', + }, + + testing: { + tokens: [ + { + name: "Euler", + symbol: "EUL", + decimals: 18, + config: { + collateralFactor: 0, + borrowFactor: 0.25, + borrowIsolated: true, + }, + }, + { + name: "Wrapped ETH", + symbol: "WETH", + decimals: 18, + config: { + collateralFactor: 0.85, + borrowFactor: 0.8, + borrowIsolated: false, + }, + }, + { + name: "Dai Stablecoin", + symbol: "DAI", + decimals: 18, + config: { + collateralFactor: 0.75, + borrowIsolated: false, + }, + }, + // { + // name: "Curve DAO Token", + // symbol: "CRV", + // decimals: 18, + // config: { + // collateralFactor: 0, + // borrowFactor: 0.7, + // borrowIsolated: true, + // }, + // }, + // { + // name: "PieDAO DOUGH v2", + // symbol: "DOUGH", + // decimals: 18, + // config: { + // collateralFactor: 0.75, + // borrowFactor: 0.8, + // borrowIsolated: true, + // }, + // }, + // { + // name: "Reputation", + // symbol: "REP", + // decimals: 18, + // config: { + // collateralFactor: 0, + // borrowFactor: 0.76, + // borrowIsolated: false, + // }, + // }, + // { + // name: "Uniswap", + // symbol: "UNI", + // decimals: 18, + // config: { + // collateralFactor: 0, + // borrowFactor: 0.76, + // borrowIsolated: false, + // }, + // }, + // { + // name: "Tether USD", + // symbol: "USDT", + // decimals: 6, + // config: { + // collateralFactor: 0.9, + // borrowFactor: 0.94, + // borrowIsolated: false, + // }, + // }, + // { + // name: "USD Coin", + // symbol: "USDC", + // decimals: 6, + // config: { + // collateralFactor: 0.9, + // borrowFactor: 0.94, + // borrowIsolated: false, + // }, + // }, + // { + // name: "Wrapped BTC", + // symbol: "WBTC", + // decimals: 8, + // config: { + // collateralFactor: 0.88, + // borrowFactor: 0.91, + // borrowIsolated: false, + // }, + // }, + // { + // name: "Compound", + // symbol: "COMP", + // decimals: 18, + // config: { + // collateralFactor: 0, + // borrowFactor: 0.7, + // borrowIsolated: true, + // }, + // }, + ], + + uniswapPools: [ + ], + + activated: [ + "WETH", + "EUL", + "DAI", + // "CRV", + // "DOUGH", + // "REP", + // "UNI", + // "USDT", + // "USDC", + // "COMP", + // "WBTC", + ], + + chainlinkPrices: { + EUL: 0.0031974695, + DAI: 0.000612, + // CRV: 0.0006578577613505, + // DOUGH: 0.000039997821658434, + // REP: 0.0036645044321926, + // UNI: 0.0040750209099273, + // USDT: 0.00062015328626584, + // USDC: 0.00061877505779954, + // WBTC: 14.28179057601, + // COMP: 0.031852903127343, + }, + + chainlinkOracles: [ + "EUL", + "DAI", + // "CRV", + // "DOUGH", + // "REP", + // "UNI", + // "USDT", + // "USDC", + // "COMP", + // "WBTC", + ] + }, +}; \ No newline at end of file diff --git a/test/lib/token-setups/testing.js b/test/lib/token-setups/testing.js index e9156de8..e20bdd8a 100644 --- a/test/lib/token-setups/testing.js +++ b/test/lib/token-setups/testing.js @@ -68,10 +68,15 @@ module.exports = { decimals: 0, }, { - name: "Unactivated Test Token", + name: "Unactivated Test Token 1", symbol: "UTST", decimals: 18, }, + { + name: "Unactivated Test Token 2", + symbol: "UTST2", + decimals: 18, + }, { name: "Test Token 11", symbol: "TST11", diff --git a/test/lib/token-setups/zktestnet.js b/test/lib/token-setups/zktestnet.js new file mode 100644 index 00000000..697fccda --- /dev/null +++ b/test/lib/token-setups/zktestnet.js @@ -0,0 +1,7 @@ +module.exports = { + riskManagerSettings: { + referenceAsset: '0x3C3881391B8D0a77D4d3849D3Ab81277519716f5', + uniswapFactory: '0x0000000000000000000000000000000000000000', + uniswapPoolInitCodeHash: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, +} \ No newline at end of file diff --git a/test/pToken.js b/test/pToken.js index 9a567071..b0ba4c90 100644 --- a/test/pToken.js +++ b/test/pToken.js @@ -136,6 +136,8 @@ et.testSet({ { send: 'pTokens.pTST.wrap', args: [et.eth(11)], }, { send: 'markets.activateMarket', args: [ctx.contracts.pTokens.pTST.address], expectError: 'e/markets/invalid-token', }, { send: 'markets.activatePToken', args: [ctx.contracts.pTokens.pTST.address], expectError: 'e/nested-ptoken', }, + + { send: 'markets.activateMarketWithChainlinkPriceFeed', args: [ctx.contracts.pTokens.pTST.address, et.AddressZero], expectError: 'e/markets/invalid-token', }, ], }) diff --git a/test/tokenFaucet.js b/test/tokenFaucet.js new file mode 100644 index 00000000..4bdd30d0 --- /dev/null +++ b/test/tokenFaucet.js @@ -0,0 +1,194 @@ +const et = require('./lib/eTestLib'); + +et.testSet({ + desc: "ERC20 test token faucet", + preActions: ctx => [ + { action: 'cb', cb: async () => { + // deploy faucet + + ctx.contracts.TestERC20Faucet = await (await ctx.factories.TestERC20TokenFaucet.deploy()).deployed(); + }} + ] +}) + + +.test({ + desc: "only owner can set threshold", + actions: ctx => [ + { from: ctx.wallet2, send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST.address, 2], + expectError: 'unauthorized', + }, + + { send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST.address, 2], }, + + { call: 'TestERC20Faucet.getThreshold', args: [ctx.contracts.tokens.TST.address], assertEql: 2, }, + ], +}) + + +.test({ + desc: "owner can set threshold for multiple tokens", + actions: ctx => [ + { send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST.address, 2], }, + + { call: 'TestERC20Faucet.getThreshold', args: [ctx.contracts.tokens.TST.address], assertEql: 2, }, + + { send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST2.address, 12], }, + + { call: 'TestERC20Faucet.getThreshold', args: [ctx.contracts.tokens.TST2.address], assertEql: 12, }, + ], +}) + + +.test({ + desc: "zero threshold reverts", + actions: ctx => [ + { send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST.address, 0], + expectError: 'setThreshold: threshold must be greater than zero', + }, + ], +}) + + +.test({ + desc: "only owner can reduce faucet balance", + actions: ctx => [ + { send: 'tokens.TST.mint', args: [ctx.contracts.TestERC20Faucet.address, 100], }, + + { call: 'tokens.TST.balanceOf', args: [ctx.contracts.TestERC20Faucet.address], assertEql: 100, }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet.address], assertEql: 0, }, + + { from: ctx.wallet2, send: 'TestERC20Faucet.reduceFaucetBalance', args: [ctx.contracts.tokens.TST.address, 2], + expectError: 'unauthorized', + }, + + { send: 'TestERC20Faucet.reduceFaucetBalance', args: [ctx.contracts.tokens.TST.address, 2], }, + + { call: 'tokens.TST.balanceOf', args: [ctx.contracts.TestERC20Faucet.address], assertEql: 98, }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet.address], assertEql: 2, }, + ], +}) + + +.test({ + desc: "owner can reduce faucet balance to zero using max uint256", + actions: ctx => [ + { send: 'tokens.TST.mint', args: [ctx.contracts.TestERC20Faucet.address, 100], }, + + { call: 'tokens.TST.balanceOf', args: [ctx.contracts.TestERC20Faucet.address], assertEql: 100, }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet.address], assertEql: 0, }, + + { send: 'TestERC20Faucet.reduceFaucetBalance', args: [ctx.contracts.tokens.TST.address, et.MaxUint256], }, + + { call: 'tokens.TST.balanceOf', args: [ctx.contracts.TestERC20Faucet.address], assertEql: 0, }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet.address], assertEql: 100, }, + ], +}) + + +.test({ + desc: "withdraw only tops up user balance and does not issue full threshold", + actions: ctx => [ + { send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST.address, et.eth(1)], }, + + { call: 'TestERC20Faucet.getThreshold', args: [ctx.contracts.tokens.TST.address], assertEql: et.eth(1), }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: 0, }, + + { send: 'tokens.TST.mint', args: [ctx.contracts.TestERC20Faucet.address, et.eth(50)], }, + + { from: ctx.wallet2, send: 'TestERC20Faucet.withdraw', args: [ctx.contracts.tokens.TST.address, ], }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: et.eth(1), }, + + { from: ctx.wallet2, send: 'tokens.TST.transfer', args: [ctx.wallet3.address, et.eth(0.5)], }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet3.address], assertEql: et.eth(0.5), }, + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: et.eth(0.5), }, + + { from: ctx.wallet2, send: 'TestERC20Faucet.withdraw', args: [ctx.contracts.tokens.TST.address, ], }, + { call: 'tokens.TST.balanceOf', args: [ctx.wallet3.address], assertEql: et.eth(0.5), }, + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: et.eth(1), }, + ], +}) + + +.test({ + desc: "withdraw reverts if threshold is not set", + actions: ctx => [ + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: 0, }, + + { send: 'tokens.TST.mint', args: [ctx.contracts.TestERC20Faucet.address, et.eth(50)], }, + + { from: ctx.wallet2, send: 'TestERC20Faucet.withdraw', args: [ctx.contracts.tokens.TST.address, ], + expectError: 'withdraw: balance not below threshold', + }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: 0, }, + ], +}) + + +.test({ + desc: "withdraw reverts if faucet balance is below withdrawal amount", + actions: ctx => [ + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: 0, }, + + { send: 'tokens.TST.mint', args: [ctx.contracts.TestERC20Faucet.address, et.eth(0.5)], }, + + { send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST.address, et.eth(1)], }, + + { from: ctx.wallet2, send: 'TestERC20Faucet.withdraw', args: [ctx.contracts.tokens.TST.address, ], + expectError: 'ERC20: transfer amount exceeds balance', + }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: 0, }, + ], +}) + + +.test({ + desc: "withdraw reverts if user balance is not below threshold", + actions: ctx => [ + { send: 'tokens.TST.mint', args: [ctx.contracts.TestERC20Faucet.address, et.eth(0.5)], }, + + { send: 'tokens.TST.mint', args: [ctx.wallet2.address, et.eth(0.5)], }, + + { send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST.address, et.eth(0.5)], }, + + { from: ctx.wallet2, send: 'TestERC20Faucet.withdraw', args: [ctx.contracts.tokens.TST.address, ], + expectError: 'withdraw: balance not below threshold', + }, + + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: et.eth(0.5), }, + ], +}) + + +.test({ + desc: "user can withdraw multiple tokkens", + actions: ctx => [ + { send: 'tokens.TST.mint', args: [ctx.contracts.TestERC20Faucet.address, et.eth(0.5)], }, + { send: 'tokens.TST2.mint', args: [ctx.contracts.TestERC20Faucet.address, et.eth(0.5)], }, + + { send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST.address, et.eth(0.25)], }, + { send: 'TestERC20Faucet.setThreshold', args: [ctx.contracts.tokens.TST2.address, et.eth(0.2)], }, + + { from: ctx.wallet2, send: 'TestERC20Faucet.withdraw', args: [ctx.contracts.tokens.TST.address, ], }, + { call: 'tokens.TST.balanceOf', args: [ctx.wallet2.address], assertEql: et.eth(0.25), }, + + { from: ctx.wallet2, send: 'TestERC20Faucet.withdraw', args: [ctx.contracts.tokens.TST2.address, ], }, + { call: 'tokens.TST2.balanceOf', args: [ctx.wallet2.address], assertEql: et.eth(0.2), }, + + { call: 'tokens.TST.balanceOf', args: [ctx.contracts.TestERC20Faucet.address], assertEql: et.eth(0.25), }, + { call: 'tokens.TST2.balanceOf', args: [ctx.contracts.TestERC20Faucet.address], assertEql: et.eth(0.3), }, + ], +}) + + + +.run(); diff --git a/test/twap.js b/test/twap.js index 04430b12..92c0d440 100644 --- a/test/twap.js +++ b/test/twap.js @@ -42,7 +42,30 @@ et.testSet({ }) +.test({ + desc: "no uniswap configured", + actions: ctx => [ + { action: 'cb', cb: async () => { + // Install RiskManager without uniswap configured + const riskManagerSettings = { + referenceAsset: ctx.contracts.tokens['WETH'].address, + uniswapFactory: ethers.constants.AddressZero, + uniswapPoolInitCodeHash: et.ethers.utils.hexZeroPad('0x', 32), + } + + ctx.contracts.modules.riskManager = await (await ctx.factories.RiskManager.deploy( + et.ethers.utils.hexZeroPad('0x', 32), + riskManagerSettings + )).deployed() + + await (await ctx.contracts.installer.connect(ctx.wallet) + .installModules([ctx.contracts.modules.riskManager.address])).wait(); + }}, + { action: 'getPrice', underlying: 'TST', expectError: 'e/unable-to-get-the-price', }, + { action: 'getPrice', underlying: 'TST2', expectError: 'e/unable-to-get-the-price', }, + ], +}) .run();