diff --git a/bun.lock b/bun.lock index 6c88c16cd..72d7a15f0 100644 --- a/bun.lock +++ b/bun.lock @@ -5,6 +5,7 @@ "name": "lifi-contracts", "dependencies": { "@arbitrum/sdk": "^3.0.0", + "@cowprotocol/cow-sdk": "^5.10.3", "@hop-protocol/sdk": "0.0.1-beta.310", "@layerzerolabs/lz-v2-utilities": "^2.3.21", "@ledgerhq/hw-app-eth": "^6.43.0", @@ -69,6 +70,8 @@ "@arbitrum/sdk": ["@arbitrum/sdk@3.7.3", "", { "dependencies": { "@ethersproject/address": "^5.0.8", "@ethersproject/bignumber": "^5.1.1", "@ethersproject/bytes": "^5.0.8", "async-mutex": "^0.4.0", "ethers": "^5.1.0" } }, "sha512-7nyPm7032+RyjfIFpJf7EKN6EQTtjEzGGemz6NgFzEFLmKj1q+QMRVj9yYKVjIM2lPMKh7Qv+DX6emsxy/5FdQ=="], + "@assemblyscript/loader": ["@assemblyscript/loader@0.9.4", "", {}, "sha512-HazVq9zwTVwGmqdwYzu7WyQ6FQVZ7SwET0KKQuKm55jD0IfUpZgN0OPIiZG3zV1iSrVYcN0bdwLRXI/VNCYsUA=="], + "@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@1.2.2", "", { "dependencies": { "@aws-crypto/util": "^1.2.2", "@aws-sdk/types": "^3.1.0", "tslib": "^1.11.1" } }, "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g=="], "@aws-crypto/util": ["@aws-crypto/util@1.2.2", "", { "dependencies": { "@aws-sdk/types": "^3.1.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } }, "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg=="], @@ -83,6 +86,12 @@ "@babel/runtime": ["@babel/runtime@7.27.1", "", {}, "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog=="], + "@cowprotocol/app-data": ["@cowprotocol/app-data@2.5.1", "", { "dependencies": { "ajv": "^8.11.0", "cross-fetch": "^3.1.5", "ipfs-only-hash": "^4.0.0", "json-stringify-deterministic": "^1.0.8", "multiformats": "^9.6.4" }, "peerDependencies": { "ethers": "^5.0.0" } }, "sha512-GvcLQ44ZUHKdSAXiZ+YCaIehtme/OIvbvL/4go1UqNLTj3jDTDkagPh7CH/z2IPwFWTADyNZO/RSzKrW5UDNaA=="], + + "@cowprotocol/contracts": ["@cowprotocol/contracts@1.8.0", "", { "peerDependencies": { "ethers": "^5.4.0" } }, "sha512-rMEHo1UBB6k4kRoWejHZNGggg6IBVt7vAd8x0FhEvjxhbq3zlAex61f9HpAcDExJNuvfwwDjsOc/7UGztCzhSw=="], + + "@cowprotocol/cow-sdk": ["@cowprotocol/cow-sdk@5.10.3", "", { "dependencies": { "@cowprotocol/app-data": "^2.4.0", "@cowprotocol/contracts": "^1.6.0", "@ethersproject/abstract-signer": "^5.7.0", "@openzeppelin/merkle-tree": "^1.0.5", "cross-fetch": "^3.1.5", "exponential-backoff": "^3.1.1", "graphql": "^16.3.0", "graphql-request": "^4.3.0", "limiter": "^3.0.0" }, "peerDependencies": { "ethers": "^5.7.2" } }, "sha512-whnfufOmJqJWw7u2HqLt6k+rw8eMH+ywmB++oxG6U6zLBdQihk18mIMz1wrNwfTUk0FFtn8g8nhrQL14oV27rg=="], + "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="], "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], @@ -95,8 +104,12 @@ "@eth-optimism/core-utils": ["@eth-optimism/core-utils@0.12.0", "", { "dependencies": { "@ethersproject/abi": "^5.7.0", "@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/address": "^5.7.0", "@ethersproject/bignumber": "^5.7.0", "@ethersproject/bytes": "^5.7.0", "@ethersproject/constants": "^5.7.0", "@ethersproject/contracts": "^5.7.0", "@ethersproject/hash": "^5.7.0", "@ethersproject/keccak256": "^5.7.0", "@ethersproject/properties": "^5.7.0", "@ethersproject/providers": "^5.7.0", "@ethersproject/rlp": "^5.7.0", "@ethersproject/transactions": "^5.7.0", "@ethersproject/web": "^5.7.0", "bufio": "^1.0.7", "chai": "^4.3.4" } }, "sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw=="], + "@ethereumjs/common": ["@ethereumjs/common@3.2.0", "", { "dependencies": { "@ethereumjs/util": "^8.1.0", "crc-32": "^1.2.0" } }, "sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA=="], + "@ethereumjs/rlp": ["@ethereumjs/rlp@5.0.2", "", { "bin": { "rlp": "bin/rlp.cjs" } }, "sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA=="], + "@ethereumjs/tx": ["@ethereumjs/tx@4.2.0", "", { "dependencies": { "@ethereumjs/common": "^3.2.0", "@ethereumjs/rlp": "^4.0.1", "@ethereumjs/util": "^8.1.0", "ethereum-cryptography": "^2.0.0" } }, "sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw=="], + "@ethereumjs/util": ["@ethereumjs/util@9.1.0", "", { "dependencies": { "@ethereumjs/rlp": "^5.0.2", "ethereum-cryptography": "^2.2.1" } }, "sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog=="], "@ethersproject/abi": ["@ethersproject/abi@5.8.0", "", { "dependencies": { "@ethersproject/address": "^5.8.0", "@ethersproject/bignumber": "^5.8.0", "@ethersproject/bytes": "^5.8.0", "@ethersproject/constants": "^5.8.0", "@ethersproject/hash": "^5.8.0", "@ethersproject/keccak256": "^5.8.0", "@ethersproject/logger": "^5.8.0", "@ethersproject/properties": "^5.8.0", "@ethersproject/strings": "^5.8.0" } }, "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q=="], @@ -187,13 +200,13 @@ "@ledgerhq/devices": ["@ledgerhq/devices@8.4.4", "", { "dependencies": { "@ledgerhq/errors": "^6.19.1", "@ledgerhq/logs": "^6.12.0", "rxjs": "^7.8.1", "semver": "^7.3.5" } }, "sha512-sz/ryhe/R687RHtevIE9RlKaV8kkKykUV4k29e7GAVwzHX1gqG+O75cu1NCJUHLbp3eABV5FdvZejqRUlLis9A=="], - "@ledgerhq/domain-service": ["@ledgerhq/domain-service@1.2.28", "", { "dependencies": { "@ledgerhq/errors": "^6.19.1", "@ledgerhq/logs": "^6.12.0", "@ledgerhq/types-live": "^6.69.0", "axios": "1.7.7", "eip55": "^2.1.1", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "sha512-coeiCO6u1VK/1NYScab3qvYrsbpxPrWjk0sbl45vTaUnseNEH13kyo8gL3GxcTerg4UTC+U0wSU6HJ9+eOyk5A=="], + "@ledgerhq/domain-service": ["@ledgerhq/domain-service@1.2.29", "", { "dependencies": { "@ledgerhq/errors": "^6.19.1", "@ledgerhq/logs": "^6.12.0", "@ledgerhq/types-live": "^6.70.0", "axios": "1.7.7", "eip55": "^2.1.1", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "sha512-A1XER1fcRO4T4/82Z9Eaag2/1yKpBedLkYsHT25/EXNmEJWEIZrmL618fI2zTax5o0c3zXgD84ZDzWYjg0olow=="], "@ledgerhq/errors": ["@ledgerhq/errors@6.19.1", "", {}, "sha512-75yK7Nnit/Gp7gdrJAz0ipp31CCgncRp+evWt6QawQEtQKYEDfGo10QywgrrBBixeRxwnMy1DP6g2oCWRf1bjw=="], "@ledgerhq/evm-tools": ["@ledgerhq/evm-tools@1.6.2", "", { "dependencies": { "@ethersproject/constants": "^5.7.0", "@ethersproject/hash": "^5.7.0", "@ledgerhq/cryptoassets-evm-signatures": "^13.5.6", "@ledgerhq/live-env": "^2.8.0", "axios": "1.7.7", "crypto-js": "4.2.0" } }, "sha512-ezdrW7qhu81YhUp5ZHysW+LqJ9SyO1JuY2cCwehJQ6HU7APof5Voglk0CaR+5JMXJX7N6tTZbu72tTAv5OmI2g=="], - "@ledgerhq/hw-app-eth": ["@ledgerhq/hw-app-eth@6.45.3", "", { "dependencies": { "@ethersproject/abi": "^5.7.0", "@ethersproject/rlp": "^5.7.0", "@ethersproject/transactions": "^5.7.0", "@ledgerhq/cryptoassets-evm-signatures": "^13.5.6", "@ledgerhq/domain-service": "^1.2.28", "@ledgerhq/errors": "^6.19.1", "@ledgerhq/evm-tools": "^1.6.2", "@ledgerhq/hw-transport": "^6.31.4", "@ledgerhq/hw-transport-mocker": "^6.29.4", "@ledgerhq/logs": "^6.12.0", "@ledgerhq/types-live": "^6.69.0", "axios": "1.7.7", "bignumber.js": "^9.1.2", "jest-sonar": "0.2.16", "semver": "^7.3.5" } }, "sha512-Divg8cA0WLdN03ebjdPE+LvxWDzISH9LaqLSQFZuXaFoCSl7ouqBZbBvinHC5TLt2f0Gdsr+ZtJJf0FY2zFQLg=="], + "@ledgerhq/hw-app-eth": ["@ledgerhq/hw-app-eth@6.45.4", "", { "dependencies": { "@ethersproject/abi": "^5.7.0", "@ethersproject/rlp": "^5.7.0", "@ethersproject/transactions": "^5.7.0", "@ledgerhq/cryptoassets-evm-signatures": "^13.5.6", "@ledgerhq/domain-service": "^1.2.29", "@ledgerhq/errors": "^6.19.1", "@ledgerhq/evm-tools": "^1.6.2", "@ledgerhq/hw-transport": "^6.31.4", "@ledgerhq/hw-transport-mocker": "^6.29.4", "@ledgerhq/logs": "^6.12.0", "@ledgerhq/types-live": "^6.70.0", "axios": "1.7.7", "bignumber.js": "^9.1.2", "jest-sonar": "0.2.16", "semver": "^7.3.5" } }, "sha512-fCDterAZd4Kb59fiJI8Ub+4Kt5thL+E3tNquSyhDTW+dWioF5Q6YcNcmRMu4bErRKejN1qCwi6/K9rT2Fhs6/g=="], "@ledgerhq/hw-transport": ["@ledgerhq/hw-transport@6.31.4", "", { "dependencies": { "@ledgerhq/devices": "^8.4.4", "@ledgerhq/errors": "^6.19.1", "@ledgerhq/logs": "^6.12.0", "events": "^3.3.0" } }, "sha512-6c1ir/cXWJm5dCWdq55NPgCJ3UuKuuxRvf//Xs36Bq9BwkV2YaRQhZITAkads83l07NAdR16hkTWqqpwFMaI6A=="], @@ -207,7 +220,7 @@ "@ledgerhq/logs": ["@ledgerhq/logs@6.12.0", "", {}, "sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA=="], - "@ledgerhq/types-live": ["@ledgerhq/types-live@6.69.0", "", { "dependencies": { "bignumber.js": "^9.1.2", "rxjs": "^7.8.1" } }, "sha512-Xi7C0vRE1RVFyKtJKHZpzYXBNh3fDz0M/Yl3lWLFQ7sOdSui+wuR/VcNmT7Z1c6ngy492RPRQL+iel2MVKrR/Q=="], + "@ledgerhq/types-live": ["@ledgerhq/types-live@6.70.0", "", { "dependencies": { "bignumber.js": "^9.1.2", "rxjs": "^7.8.1" } }, "sha512-xJ9VKf5AQpROIhM2Tm8U4/5V50u6PZhvv9zVkemZvJPw7eqzW3VUq5wLEN6TJWN4JII3D5YDc75x8ws5w9ma1A=="], "@maticnetwork/maticjs": ["@maticnetwork/maticjs@2.0.51", "", { "dependencies": { "@maticnetwork/meta": "^2.4.21", "axios": "^0.21.1", "bn.js": "5.0.0", "debug": "^4.1.1", "eth-sig-util": "^2.5.3", "ethereumjs-block": "2.2.0", "ethereumjs-tx": "1.3.7", "ethereumjs-util": "^5.2.0", "merkle-patricia-tree": "2.3.2", "query-string": "6.8.1", "web3": "^1.5.2" } }, "sha512-D4054vZCj/Jp2K9HtNJd0qSn+lRTttMjHzkwrTxd5f2mB0zVybhOrZj5q5Xcka7a5CAfD9nBeZRf5hvdcnODig=="], @@ -215,8 +228,18 @@ "@mayanfinance/swap-sdk": ["@mayanfinance/swap-sdk@8.6.0", "", { "dependencies": { "@solana/buffer-layout": "^4 || ^3", "@solana/web3.js": "^1.87.6", "cross-fetch": "^3.1.5", "ethers": "^6", "js-sha256": "^0.9.0", "js-sha3": "^0.8.0" } }, "sha512-Flk8+9BkMlmu2HI+cwEohlmwnNViUapXORsYZEbDzy1xhLdJQOb2V0ykw9TqXKcfp9BAdD17oqEyCzZgkXGC4g=="], + "@metamask/abi-utils": ["@metamask/abi-utils@2.0.4", "", { "dependencies": { "@metamask/superstruct": "^3.1.0", "@metamask/utils": "^9.0.0" } }, "sha512-StnIgUB75x7a7AgUhiaUZDpCsqGp7VkNnZh2XivXkJ6mPkE83U8ARGQj5MbRis7VJY8BC5V1AbB1fjdh0hupPQ=="], + + "@metamask/superstruct": ["@metamask/superstruct@3.2.1", "", {}, "sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g=="], + + "@metamask/utils": ["@metamask/utils@9.3.0", "", { "dependencies": { "@ethereumjs/tx": "^4.2.0", "@metamask/superstruct": "^3.1.0", "@noble/hashes": "^1.3.1", "@scure/base": "^1.1.3", "@types/debug": "^4.1.7", "debug": "^4.3.4", "pony-cause": "^2.1.10", "semver": "^7.5.4", "uuid": "^9.0.1" } }, "sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g=="], + "@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.2.2", "", { "dependencies": { "sparse-bitfield": "^3.0.3" } }, "sha512-EB0O3SCSNRUFk66iRCpI+cXzIjdswfCs7F6nOC3RAGJ7xr5YhaicvsRwJ9eyzYvYRlCSDUO/c7g4yNulxKC1WA=="], + "@multiformats/base-x": ["@multiformats/base-x@4.0.1", "", {}, "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw=="], + + "@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="], + "@noble/curves": ["@noble/curves@1.8.2", "", { "dependencies": { "@noble/hashes": "1.7.2" } }, "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g=="], "@noble/hashes": ["@noble/hashes@1.7.2", "", {}, "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ=="], @@ -289,6 +312,8 @@ "@octokit/types": ["@octokit/types@14.0.0", "", { "dependencies": { "@octokit/openapi-types": "^25.0.0" } }, "sha512-VVmZP0lEhbo2O1pdq63gZFiGCKkm8PPp8AUOijlwPO6hojEVjspA0MWKP7E4hbvGxzFKNqKr6p0IYtOH/Wf/zA=="], + "@openzeppelin/merkle-tree": ["@openzeppelin/merkle-tree@1.0.8", "", { "dependencies": { "@metamask/abi-utils": "^2.0.4", "ethereum-cryptography": "^3.0.0" } }, "sha512-E2c9/Y3vjZXwVvPZKqCKUn7upnvam1P1ZhowJyZVQSkzZm5WhumtaRr+wkUXrZVfkIc7Gfrl7xzabElqDL09ow=="], + "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], "@pnpm/config.env-replace": ["@pnpm/config.env-replace@1.1.0", "", {}, "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w=="], @@ -347,11 +372,11 @@ "@solana/buffer-layout": ["@solana/buffer-layout@4.0.1", "", { "dependencies": { "buffer": "~6.0.3" } }, "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA=="], - "@solana/codecs-core": ["@solana/codecs-core@2.1.0", "", { "dependencies": { "@solana/errors": "2.1.0" }, "peerDependencies": { "typescript": ">=5" } }, "sha512-SR7pKtmJBg2mhmkel2NeHA1pz06QeQXdMv8WJoIR9m8F/hw80K/612uaYbwTt2nkK0jg/Qn/rNSd7EcJ4SBGjw=="], + "@solana/codecs-core": ["@solana/codecs-core@2.1.1", "", { "dependencies": { "@solana/errors": "2.1.1" }, "peerDependencies": { "typescript": ">=5.3.3" } }, "sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg=="], - "@solana/codecs-numbers": ["@solana/codecs-numbers@2.1.0", "", { "dependencies": { "@solana/codecs-core": "2.1.0", "@solana/errors": "2.1.0" }, "peerDependencies": { "typescript": ">=5" } }, "sha512-XMu4yw5iCgQnMKsxSWPPOrGgtaohmupN3eyAtYv3K3C/MJEc5V90h74k5B1GUCiHvcrdUDO9RclNjD9lgbjFag=="], + "@solana/codecs-numbers": ["@solana/codecs-numbers@2.1.1", "", { "dependencies": { "@solana/codecs-core": "2.1.1", "@solana/errors": "2.1.1" }, "peerDependencies": { "typescript": ">=5.3.3" } }, "sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ=="], - "@solana/errors": ["@solana/errors@2.1.0", "", { "dependencies": { "chalk": "^5.3.0", "commander": "^13.1.0" }, "peerDependencies": { "typescript": ">=5" }, "bin": { "errors": "bin/cli.mjs" } }, "sha512-l+GxAv0Ar4d3c3PlZdA9G++wFYZREEbbRyAFP8+n8HSg0vudCuzogh/13io6hYuUhG/9Ve8ARZNamhV7UScKNw=="], + "@solana/errors": ["@solana/errors@2.1.1", "", { "dependencies": { "chalk": "^5.4.1", "commander": "^13.1.0" }, "peerDependencies": { "typescript": ">=5.3.3" }, "bin": { "errors": "bin/cli.mjs" } }, "sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw=="], "@solana/web3.js": ["@solana/web3.js@1.98.2", "", { "dependencies": { "@babel/runtime": "^7.25.0", "@noble/curves": "^1.4.2", "@noble/hashes": "^1.4.0", "@solana/buffer-layout": "^4.0.1", "@solana/codecs-numbers": "^2.1.0", "agentkeepalive": "^4.5.0", "bn.js": "^5.2.1", "borsh": "^0.7.0", "bs58": "^4.0.1", "buffer": "6.0.3", "fast-stable-stringify": "^1.0.0", "jayson": "^4.1.1", "node-fetch": "^2.7.0", "rpc-websockets": "^9.0.2", "superstruct": "^2.0.2" } }, "sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A=="], @@ -367,6 +392,8 @@ "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="], + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + "@types/fined": ["@types/fined@1.1.5", "", {}, "sha512-2N93vadEGDFhASTIRbizbl4bNqpMOId5zZfj6hHqYZfEzEfO9onnU4Im8xvzo8uudySDveDHBOOSlTWf38ErfQ=="], "@types/glob": ["@types/glob@7.2.0", "", { "dependencies": { "@types/minimatch": "*", "@types/node": "*" } }, "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA=="], @@ -391,10 +418,16 @@ "@types/minimatch": ["@types/minimatch@5.1.2", "", {}, "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA=="], + "@types/minimist": ["@types/minimist@1.2.5", "", {}, "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag=="], + "@types/mkdirp": ["@types/mkdirp@0.5.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg=="], + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + "@types/node": ["@types/node@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="], + "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], + "@types/pbkdf2": ["@types/pbkdf2@3.1.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew=="], "@types/pino": ["@types/pino@7.0.5", "", { "dependencies": { "pino": "*" } }, "sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg=="], @@ -619,6 +652,8 @@ "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], + "camelcase-keys": ["camelcase-keys@6.2.2", "", { "dependencies": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", "quick-lru": "^4.0.1" } }, "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg=="], + "capital-case": ["capital-case@1.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A=="], "chai": ["chai@4.5.0", "", { "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", "deep-eql": "^4.1.3", "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", "type-detect": "^4.1.0" } }, "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw=="], @@ -637,6 +672,8 @@ "ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="], + "cids": ["cids@1.1.9", "", { "dependencies": { "multibase": "^4.0.1", "multicodec": "^3.0.1", "multihashes": "^4.0.1", "uint8arrays": "^3.0.0" } }, "sha512-l11hWRfugIcbGuTZwAM5PwpjPPjyb6UZOGwlHSnOBV5o07XhQ4gNpBN67FbODvpjyHtd+0Xs6KNvUcGBiDRsdg=="], + "cipher-base": ["cipher-base@1.0.6", "", { "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1" } }, "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw=="], "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], @@ -711,10 +748,12 @@ "death": ["death@1.1.0", "", {}, "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w=="], - "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], "decamelize": ["decamelize@4.0.0", "", {}, "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ=="], + "decamelize-keys": ["decamelize-keys@1.1.1", "", { "dependencies": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" } }, "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg=="], + "decimal.js": ["decimal.js@10.5.0", "", {}, "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw=="], "decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="], @@ -895,6 +934,8 @@ "external-editor": ["external-editor@3.1.0", "", { "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" } }, "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew=="], + "extract-files": ["extract-files@9.0.0", "", {}, "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ=="], + "eyes": ["eyes@0.1.8", "", {}, "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ=="], "fast-base64-decode": ["fast-base64-decode@1.0.0", "", {}, "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q=="], @@ -961,7 +1002,7 @@ "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], - "form-data": ["form-data@4.0.2", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" } }, "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w=="], + "form-data": ["form-data@3.0.3", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.35" } }, "sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w=="], "form-data-encoder": ["form-data-encoder@2.1.4", "", {}, "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw=="], @@ -1033,10 +1074,18 @@ "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], + "graphql": ["graphql@16.11.0", "", {}, "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw=="], + + "graphql-request": ["graphql-request@4.3.0", "", { "dependencies": { "cross-fetch": "^3.1.5", "extract-files": "^9.0.0", "form-data": "^3.0.0" }, "peerDependencies": { "graphql": "14 - 16" } }, "sha512-2v6hQViJvSsifK606AliqiNiijb1uwWp6Re7o0RTyH+uRTv/u7Uqm2g4Fjq/LgZIzARB38RZEvVBFOQOVdlBow=="], + "gtoken": ["gtoken@5.3.2", "", { "dependencies": { "gaxios": "^4.0.0", "google-p12-pem": "^3.1.3", "jws": "^4.0.0" } }, "sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ=="], + "hamt-sharding": ["hamt-sharding@2.0.1", "", { "dependencies": { "sparse-array": "^1.3.1", "uint8arrays": "^3.0.0" } }, "sha512-vnjrmdXG9dDs1m/H4iJ6z0JFI2NtgsW5keRkTcM85NGak69Mkf5PHUqBz+Xs0T4sg0ppvj9O5EGAJo40FTxmmA=="], + "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="], + "hard-rejection": ["hard-rejection@2.1.0", "", {}, "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA=="], + "hardhat": ["hardhat@2.24.0", "", { "dependencies": { "@ethereumjs/util": "^9.1.0", "@ethersproject/abi": "^5.1.2", "@nomicfoundation/edr": "^0.11.0", "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", "adm-zip": "^0.4.16", "aggregate-error": "^3.0.0", "ansi-escapes": "^4.3.0", "boxen": "^5.1.2", "chokidar": "^4.0.0", "ci-info": "^2.0.0", "debug": "^4.1.1", "enquirer": "^2.3.0", "env-paths": "^2.2.0", "ethereum-cryptography": "^1.0.3", "find-up": "^5.0.0", "fp-ts": "1.19.3", "fs-extra": "^7.0.1", "immutable": "^4.0.0-rc.12", "io-ts": "1.10.4", "json-stream-stringify": "^3.1.4", "keccak": "^3.0.2", "lodash": "^4.17.11", "micro-eth-signer": "^0.14.0", "mnemonist": "^0.38.0", "mocha": "^10.0.0", "p-map": "^4.0.0", "picocolors": "^1.1.0", "raw-body": "^2.4.1", "resolve": "1.17.0", "semver": "^6.3.0", "solc": "0.8.26", "source-map-support": "^0.5.13", "stacktrace-parser": "^0.1.10", "tinyglobby": "^0.2.6", "tsort": "0.0.1", "undici": "^5.14.0", "uuid": "^8.3.2", "ws": "^7.4.6" }, "peerDependencies": { "ts-node": "*", "typescript": "*" }, "optionalPeers": ["ts-node", "typescript"], "bin": { "hardhat": "internal/cli/bootstrap.js" } }, "sha512-wDkD5GPmttYv21MR7tGDkyQ22tO2V86OEV8pA7NcXWYUpibe8XZ2EanXCeRHO61vwEx0f7/M+NqrhJwasaNMJg=="], "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="], @@ -1069,7 +1118,9 @@ "homedir-polyfill": ["homedir-polyfill@1.0.3", "", { "dependencies": { "parse-passwd": "^1.0.0" } }, "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA=="], - "http-cache-semantics": ["http-cache-semantics@4.1.1", "", {}, "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="], + "hosted-git-info": ["hosted-git-info@4.1.0", "", { "dependencies": { "lru-cache": "^6.0.0" } }, "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA=="], + + "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], "http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="], @@ -1111,6 +1162,8 @@ "inquirer": ["inquirer@8.2.6", "", { "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", "cli-cursor": "^3.1.0", "cli-width": "^3.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", "lodash": "^4.17.21", "mute-stream": "0.0.8", "ora": "^5.4.1", "run-async": "^2.4.0", "rxjs": "^7.5.5", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6", "wrap-ansi": "^6.0.1" } }, "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg=="], + "interface-ipld-format": ["interface-ipld-format@1.0.1", "", { "dependencies": { "cids": "^1.1.6", "multicodec": "^3.0.1", "multihashes": "^4.0.2" } }, "sha512-WV/ar+KQJVoQpqRDYdo7YPGYIUHJxCuOEhdvsRpzLqoOIVCqPKdMMYmsLL1nCRsF3yYNio+PAJbCKiv6drrEAg=="], + "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="], "interpret": ["interpret@2.2.0", "", {}, "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw=="], @@ -1119,6 +1172,14 @@ "ip-address": ["ip-address@9.0.5", "", { "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" } }, "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g=="], + "ipfs-only-hash": ["ipfs-only-hash@4.0.0", "", { "dependencies": { "ipfs-unixfs-importer": "^7.0.1", "meow": "^9.0.0" }, "bin": { "ipfs-only-hash": "cli.js" } }, "sha512-TE1DZCvfw8i3gcsTq3P4TFx3cKFJ3sluu/J3XINkJhIN9OwJgNMqKA+WnKx6ByCb1IoPXsTp1KM7tupElb6SyA=="], + + "ipfs-unixfs": ["ipfs-unixfs@4.0.3", "", { "dependencies": { "err-code": "^3.0.1", "protobufjs": "^6.10.2" } }, "sha512-hzJ3X4vlKT8FQ3Xc4M1szaFVjsc1ZydN+E4VQ91aXxfpjFn9G2wsMo1EFdAXNq/BUnN5dgqIOMP5zRYr3DTsAw=="], + + "ipfs-unixfs-importer": ["ipfs-unixfs-importer@7.0.3", "", { "dependencies": { "bl": "^5.0.0", "cids": "^1.1.5", "err-code": "^3.0.1", "hamt-sharding": "^2.0.0", "ipfs-unixfs": "^4.0.3", "ipld-dag-pb": "^0.22.2", "it-all": "^1.0.5", "it-batch": "^1.0.8", "it-first": "^1.0.6", "it-parallel-batch": "^1.0.9", "merge-options": "^3.0.4", "multihashing-async": "^2.1.0", "rabin-wasm": "^0.1.4", "uint8arrays": "^2.1.2" } }, "sha512-qeFOlD3AQtGzr90sr5Tq1Bi8pT5Nr2tSI8z310m7R4JDYgZc6J1PEZO3XZQ8l1kuGoqlAppBZuOYmPEqaHcVQQ=="], + + "ipld-dag-pb": ["ipld-dag-pb@0.22.3", "", { "dependencies": { "cids": "^1.0.0", "interface-ipld-format": "^1.0.0", "multicodec": "^3.0.1", "multihashing-async": "^2.0.0", "protobufjs": "^6.10.2", "stable": "^0.1.8", "uint8arrays": "^2.0.5" } }, "sha512-dfG5C5OVAR4FEP7Al2CrHWvAyIM7UhAQrjnOYOIxXGQz5NlEj6wGX0XQf6Ru6or1na6upvV3NQfstapQG8X2rg=="], + "is": ["is@3.3.0", "", {}, "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg=="], "is-absolute": ["is-absolute@1.0.0", "", { "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" } }, "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA=="], @@ -1227,6 +1288,14 @@ "isows": ["isows@1.0.6", "", { "peerDependencies": { "ws": "*" } }, "sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw=="], + "it-all": ["it-all@1.0.6", "", {}, "sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A=="], + + "it-batch": ["it-batch@1.0.9", "", {}, "sha512-7Q7HXewMhNFltTsAMdSz6luNhyhkhEtGGbYek/8Xb/GiqYMtwUmopE1ocPSiJKKp3rM4Dt045sNFoUu+KZGNyA=="], + + "it-first": ["it-first@1.0.7", "", {}, "sha512-nvJKZoBpZD/6Rtde6FXqwDqDZGF1sCADmr2Zoc0hZsIvnE449gRFnGctxDf09Bzc/FWnHXAdaHVIetY6lrE0/g=="], + + "it-parallel-batch": ["it-parallel-batch@1.0.11", "", { "dependencies": { "it-batch": "^1.0.9" } }, "sha512-UWsWHv/kqBpMRmyZJzlmZeoAMA0F3SZr08FBdbhtbe+MtoEBgr/ZUAKrnenhXCBrsopy76QjRH2K/V8kNdupbQ=="], + "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], "jayson": ["jayson@4.2.0", "", { "dependencies": { "@types/connect": "^3.4.33", "@types/node": "^12.12.54", "@types/ws": "^7.4.4", "commander": "^2.20.3", "delay": "^5.0.0", "es6-promisify": "^5.0.0", "eyes": "^0.1.8", "isomorphic-ws": "^4.0.1", "json-stringify-safe": "^5.0.1", "stream-json": "^1.9.1", "uuid": "^8.3.2", "ws": "^7.5.10" }, "bin": { "jayson": "bin/jayson.js" } }, "sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg=="], @@ -1259,6 +1328,8 @@ "json-stream-stringify": ["json-stream-stringify@3.1.6", "", {}, "sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog=="], + "json-stringify-deterministic": ["json-stringify-deterministic@1.0.12", "", {}, "sha512-q3PN0lbUdv0pmurkBNdJH3pfFvOTL/Zp0lquqpvcjfKzt6Y0j49EPHAmVHCAS4Ceq/Y+PejWTzyiVpoY71+D6g=="], + "json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], "json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="], @@ -1299,6 +1370,8 @@ "lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="], + "limiter": ["limiter@3.0.0", "", {}, "sha512-hev7DuXojsTFl2YwyzUJMDnZ/qBDd3yZQLSH3aD4tdL1cqfc3TMnoecEJtWFaQFdErZsKoFMBTxF/FBSkgDbEg=="], + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], "lint-staged": ["lint-staged@13.3.0", "", { "dependencies": { "chalk": "5.3.0", "commander": "11.0.0", "debug": "4.3.4", "execa": "7.2.0", "lilconfig": "2.1.0", "listr2": "6.6.1", "micromatch": "4.0.5", "pidtree": "0.6.0", "string-argv": "0.3.2", "yaml": "2.3.1" }, "bin": { "lint-staged": "bin/lint-staged.js" } }, "sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ=="], @@ -1347,6 +1420,8 @@ "map-cache": ["map-cache@0.2.2", "", {}, "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg=="], + "map-obj": ["map-obj@4.3.0", "", {}, "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ=="], + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], "md5.js": ["md5.js@1.3.5", "", { "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" } }, "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg=="], @@ -1357,6 +1432,10 @@ "memorystream": ["memorystream@0.3.1", "", {}, "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw=="], + "meow": ["meow@9.0.0", "", { "dependencies": { "@types/minimist": "^1.2.0", "camelcase-keys": "^6.2.2", "decamelize": "^1.2.0", "decamelize-keys": "^1.1.0", "hard-rejection": "^2.1.0", "minimist-options": "4.1.0", "normalize-package-data": "^3.0.0", "read-pkg-up": "^7.0.1", "redent": "^3.0.0", "trim-newlines": "^3.0.0", "type-fest": "^0.18.0", "yargs-parser": "^20.2.3" } }, "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ=="], + + "merge-options": ["merge-options@3.0.4", "", { "dependencies": { "is-plain-obj": "^2.1.0" } }, "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ=="], + "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], @@ -1381,6 +1460,8 @@ "mimic-response": ["mimic-response@4.0.0", "", {}, "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg=="], + "min-indent": ["min-indent@1.0.1", "", {}, "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="], + "minimalistic-assert": ["minimalistic-assert@1.0.1", "", {}, "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="], "minimalistic-crypto-utils": ["minimalistic-crypto-utils@1.0.1", "", {}, "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="], @@ -1389,6 +1470,8 @@ "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + "minimist-options": ["minimist-options@4.1.0", "", { "dependencies": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", "kind-of": "^6.0.3" } }, "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A=="], + "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], "minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], @@ -1419,6 +1502,18 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "multibase": ["multibase@4.0.6", "", { "dependencies": { "@multiformats/base-x": "^4.0.1" } }, "sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ=="], + + "multicodec": ["multicodec@3.2.1", "", { "dependencies": { "uint8arrays": "^3.0.0", "varint": "^6.0.0" } }, "sha512-+expTPftro8VAW8kfvcuNNNBgb9gPeNYV9dn+z1kJRWF2vih+/S79f2RVeIwmrJBUJ6NT9IUPWnZDQvegEh5pw=="], + + "multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], + + "multihashes": ["multihashes@4.0.3", "", { "dependencies": { "multibase": "^4.0.1", "uint8arrays": "^3.0.0", "varint": "^5.0.2" } }, "sha512-0AhMH7Iu95XjDLxIeuCOOE4t9+vQZsACyKZ9Fxw2pcsRmlX4iCn1mby0hS0bb+nQOVpdQYWPpnyusw4da5RPhA=="], + + "multihashing-async": ["multihashing-async@2.1.4", "", { "dependencies": { "blakejs": "^1.1.0", "err-code": "^3.0.0", "js-sha3": "^0.8.0", "multihashes": "^4.0.1", "murmurhash3js-revisited": "^3.0.0", "uint8arrays": "^3.0.0" } }, "sha512-sB1MiQXPSBTNRVSJc2zM157PXgDtud2nMFUEIvBrsq5Wv96sUclMRK/ecjoP1T/W61UJBqt4tCTwMkUpt2Gbzg=="], + + "murmurhash3js-revisited": ["murmurhash3js-revisited@3.0.0", "", {}, "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g=="], + "mute-stream": ["mute-stream@0.0.8", "", {}, "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="], "napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="], @@ -1455,6 +1550,8 @@ "nopt": ["nopt@7.2.1", "", { "dependencies": { "abbrev": "^2.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w=="], + "normalize-package-data": ["normalize-package-data@3.0.3", "", { "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" } }, "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA=="], + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], "normalize-url": ["normalize-url@8.0.1", "", {}, "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w=="], @@ -1513,6 +1610,8 @@ "p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="], + "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], + "package-json": ["package-json@8.1.1", "", { "dependencies": { "got": "^12.1.0", "registry-auth-token": "^5.0.1", "registry-url": "^6.0.0", "semver": "^7.3.7" } }, "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA=="], "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], @@ -1571,6 +1670,8 @@ "pluralize": ["pluralize@8.0.0", "", {}, "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="], + "pony-cause": ["pony-cause@2.1.11", "", {}, "sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg=="], + "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], "postinstall-postinstall": ["postinstall-postinstall@2.1.0", "", {}, "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ=="], @@ -1615,6 +1716,8 @@ "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], + "rabin-wasm": ["rabin-wasm@0.1.5", "", { "dependencies": { "@assemblyscript/loader": "^0.9.4", "bl": "^5.0.0", "debug": "^4.3.1", "minimist": "^1.2.5", "node-fetch": "^2.6.1", "readable-stream": "^3.6.0" }, "bin": { "rabin-wasm": "cli/bin.js" } }, "sha512-uWgQTo7pim1Rnj5TuWcCewRDTf0PEFTSlaUjWP4eY9EbLV9em08v89oCz/WO+wRxpYuO36XEHp4wgYQnAgOHzA=="], + "randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="], "raw-body": ["raw-body@2.5.2", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA=="], @@ -1625,6 +1728,10 @@ "react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="], + "read-pkg": ["read-pkg@5.2.0", "", { "dependencies": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", "parse-json": "^5.0.0", "type-fest": "^0.6.0" } }, "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg=="], + + "read-pkg-up": ["read-pkg-up@7.0.1", "", { "dependencies": { "find-up": "^4.1.0", "read-pkg": "^5.2.0", "type-fest": "^0.8.1" } }, "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg=="], + "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], @@ -1635,6 +1742,8 @@ "recursive-readdir": ["recursive-readdir@2.2.3", "", { "dependencies": { "minimatch": "^3.0.5" } }, "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA=="], + "redent": ["redent@3.0.0", "", { "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" } }, "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg=="], + "reduce-flatten": ["reduce-flatten@2.0.0", "", {}, "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w=="], "reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="], @@ -1705,7 +1814,7 @@ "semaphore": ["semaphore@1.1.0", "", {}, "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA=="], - "semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], + "semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], "sentence-case": ["sentence-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg=="], @@ -1769,8 +1878,18 @@ "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + "sparse-array": ["sparse-array@1.3.2", "", {}, "sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg=="], + "sparse-bitfield": ["sparse-bitfield@3.0.3", "", { "dependencies": { "memory-pager": "^1.0.2" } }, "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ=="], + "spdx-correct": ["spdx-correct@3.2.0", "", { "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA=="], + + "spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], + + "spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], + + "spdx-license-ids": ["spdx-license-ids@3.0.21", "", {}, "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg=="], + "split-array-stream": ["split-array-stream@2.0.0", "", { "dependencies": { "is-stream-ended": "^0.1.4" } }, "sha512-hmMswlVY91WvGMxs0k8MRgq8zb2mSen4FmDNc5AFiTWtrBpdZN6nwD6kROVe4vNL+ywrvbCKsWVCnEd4riELIg=="], "split-on-first": ["split-on-first@1.1.0", "", {}, "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="], @@ -1781,6 +1900,8 @@ "ssri": ["ssri@10.0.6", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ=="], + "stable": ["stable@0.1.8", "", {}, "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w=="], + "stacktrace-parser": ["stacktrace-parser@0.1.11", "", { "dependencies": { "type-fest": "^0.7.1" } }, "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg=="], "statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], @@ -1823,6 +1944,8 @@ "strip-hex-prefix": ["strip-hex-prefix@1.0.0", "", { "dependencies": { "is-hex-prefixed": "1.0.0" } }, "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A=="], + "strip-indent": ["strip-indent@3.0.0", "", { "dependencies": { "min-indent": "^1.0.0" } }, "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="], + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], "stubs": ["stubs@3.0.0", "", {}, "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw=="], @@ -1871,6 +1994,8 @@ "treeify": ["treeify@1.1.0", "", {}, "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A=="], + "trim-newlines": ["trim-newlines@3.0.1", "", {}, "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw=="], + "ts-api-utils": ["ts-api-utils@1.4.3", "", { "peerDependencies": { "typescript": ">=4.2.0" } }, "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw=="], "ts-command-line-args": ["ts-command-line-args@2.5.1", "", { "dependencies": { "chalk": "^4.1.0", "command-line-args": "^5.1.1", "command-line-usage": "^6.1.0", "string-format": "^2.0.0" }, "bin": { "write-markdown": "dist/write-markdown.js" } }, "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw=="], @@ -1917,6 +2042,8 @@ "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], + "uint8arrays": ["uint8arrays@2.1.10", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-Q9/hhJa2836nQfEJSZTmr+pg9+cDJS9XEAp7N2Vg5MzL3bK/mkMVfjscRGYruP9jNda6MAdf4QD/y78gSzkp6A=="], + "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="], "unc-path-regex": ["unc-path-regex@0.1.2", "", {}, "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="], @@ -1931,7 +2058,7 @@ "unique-slug": ["unique-slug@4.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ=="], - "universal-user-agent": ["universal-user-agent@7.0.2", "", {}, "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="], + "universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="], "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], @@ -1959,7 +2086,11 @@ "v8flags": ["v8flags@4.0.1", "", {}, "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg=="], - "viem": ["viem@2.29.1", "", { "dependencies": { "@noble/curves": "1.8.2", "@noble/hashes": "1.7.2", "@scure/bip32": "1.6.2", "@scure/bip39": "1.5.4", "abitype": "1.0.8", "isows": "1.0.6", "ox": "0.6.9", "ws": "8.18.1" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-mhLn0vDdsxZ4taB7XYgnIVNvXASm60KyPAkvw4k8uNCQ+HLH+5jUgKvLg4AP3y6VJxsgiVPwqUt0dJANDF5DZA=="], + "validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="], + + "varint": ["varint@6.0.0", "", {}, "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="], + + "viem": ["viem@2.29.2", "", { "dependencies": { "@noble/curves": "1.8.2", "@noble/hashes": "1.7.2", "@scure/bip32": "1.6.2", "@scure/bip39": "1.5.4", "abitype": "1.0.8", "isows": "1.0.6", "ox": "0.6.9", "ws": "8.18.1" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-cukRxab90jvQ+TDD84sU3qB3UmejYqgCw4cX8SfWzvh7JPfZXI3kAMUaT5OSR2As1Mgvx1EJawccwPjGqkSSwA=="], "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], @@ -2057,7 +2188,7 @@ "zod": ["zod@3.24.4", "", {}, "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg=="], - "zx": ["zx@8.5.3", "", { "bin": { "zx": "build/cli.js" } }, "sha512-TsGLAt8Ngr4wDXLZmN9BT+6FWVLFbqdQ0qpXkV3tIfH7F+MgN/WUeSY7W4nNqAntjWunmnRaznpyxtJRPhCbUQ=="], + "zx": ["zx@8.5.4", "", { "bin": { "zx": "build/cli.js" } }, "sha512-44oKea9Sa8ZnOkTnS6fRJpg3quzgnbB43nLrVfYnqE86J4sxgZMUDLezzKET/FdOAVkF4X+Alm9Bume+W+RW9Q=="], "@aws-crypto/sha256-js/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], @@ -2067,6 +2198,16 @@ "@aws-sdk/util-utf8-browser/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "@cowprotocol/app-data/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + + "@ethereumjs/common/@ethereumjs/util": ["@ethereumjs/util@8.1.0", "", { "dependencies": { "@ethereumjs/rlp": "^4.0.1", "ethereum-cryptography": "^2.0.0", "micro-ftch": "^0.3.1" } }, "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA=="], + + "@ethereumjs/tx/@ethereumjs/rlp": ["@ethereumjs/rlp@4.0.1", "", { "bin": { "rlp": "bin/rlp" } }, "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw=="], + + "@ethereumjs/tx/@ethereumjs/util": ["@ethereumjs/util@8.1.0", "", { "dependencies": { "@ethereumjs/rlp": "^4.0.1", "ethereum-cryptography": "^2.0.0", "micro-ftch": "^0.3.1" } }, "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA=="], + + "@ethereumjs/tx/ethereum-cryptography": ["ethereum-cryptography@2.2.1", "", { "dependencies": { "@noble/curves": "1.4.2", "@noble/hashes": "1.4.0", "@scure/bip32": "1.4.0", "@scure/bip39": "1.3.0" } }, "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg=="], + "@ethereumjs/util/ethereum-cryptography": ["ethereum-cryptography@2.2.1", "", { "dependencies": { "@noble/curves": "1.4.2", "@noble/hashes": "1.4.0", "@scure/bip32": "1.4.0", "@scure/bip39": "1.3.0" } }, "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg=="], "@ethersproject/json-wallets/aes-js": ["aes-js@3.0.0", "", {}, "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw=="], @@ -2091,10 +2232,16 @@ "@mayanfinance/swap-sdk/ethers": ["ethers@6.14.0", "", { "dependencies": { "@adraffy/ens-normalize": "1.10.1", "@noble/curves": "1.2.0", "@noble/hashes": "1.3.2", "@types/node": "22.7.5", "aes-js": "4.0.0-beta.5", "tslib": "2.7.0", "ws": "8.17.1" } }, "sha512-KgHwltNSMdbrGWEyKkM0Rt2s+u1nDH/5BVDQakLinzGEJi4bWindBzZSCC4gKsbZjwDTI6ex/8suR9Ihbmz4IQ=="], + "@metamask/utils/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + + "@metamask/utils/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], + "@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="], "@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="], + "@openzeppelin/merkle-tree/ethereum-cryptography": ["ethereum-cryptography@3.2.0", "", { "dependencies": { "@noble/ciphers": "1.3.0", "@noble/curves": "1.9.0", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0" } }, "sha512-Urr5YVsalH+Jo0sYkTkv1MyI9bLYZwW8BENZCeE1QYaTHETEYx0Nv/SVsWkSqpYrzweg6d8KMY1wTjH/1m/BIg=="], + "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="], "@sentry/core/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], @@ -2171,13 +2318,17 @@ "async-retry/retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="], + "axios/form-data": ["form-data@4.0.2", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" } }, "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w=="], + "boxen/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "cacache/fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], - "camel-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "camelcase-keys/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="], - "capital-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "camelcase-keys/quick-lru": ["quick-lru@4.0.1", "", {}, "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g=="], + + "cids/uint8arrays": ["uint8arrays@3.1.1", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg=="], "cli-truncate/slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="], @@ -2191,10 +2342,12 @@ "command-line-usage/typical": ["typical@5.2.0", "", {}, "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="], - "constant-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + "decamelize-keys/decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="], + + "decamelize-keys/map-obj": ["map-obj@1.0.1", "", {}, "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg=="], + "decompress-response/mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], "defender-base-client/axios": ["axios@0.21.4", "", { "dependencies": { "follow-redirects": "^1.14.0" } }, "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg=="], @@ -2209,8 +2362,6 @@ "del/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], - "dot-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "elliptic/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="], "encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], @@ -2221,6 +2372,8 @@ "escodegen/source-map": ["source-map@0.2.0", "", { "dependencies": { "amdefine": ">=0.0.4" } }, "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA=="], + "eslint/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="], + "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], "eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], @@ -2261,6 +2414,8 @@ "figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + "findup-sync/micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + "flat-cache/rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], "foreground-child/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], @@ -2277,12 +2432,14 @@ "global-prefix/which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "./bin/which" } }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="], - "globby/glob": ["glob@7.1.7", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ=="], + "globby/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], "globby/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], "google-auth-library/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], + "hamt-sharding/uint8arrays": ["uint8arrays@3.1.1", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg=="], + "hardhat/fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="], "hardhat/resolve": ["resolve@1.17.0", "", { "dependencies": { "path-parse": "^1.0.6" } }, "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w=="], @@ -2291,7 +2448,7 @@ "hardhat/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], - "header-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "hosted-git-info/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], "inquirer/cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="], @@ -2301,6 +2458,10 @@ "ip-address/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], + "ipfs-unixfs/err-code": ["err-code@3.0.1", "", {}, "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA=="], + + "ipfs-unixfs-importer/err-code": ["err-code@3.0.1", "", {}, "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA=="], + "jayson/@types/node": ["@types/node@12.20.55", "", {}, "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="], "jayson/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], @@ -2335,8 +2496,16 @@ "memdown/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + "meow/decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="], + + "meow/type-fest": ["type-fest@0.18.1", "", {}, "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw=="], + "merkle-patricia-tree/readable-stream": ["readable-stream@2.3.8", "", { "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" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + "minimist-options/arrify": ["arrify@1.0.1", "", {}, "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA=="], + + "minimist-options/is-plain-obj": ["is-plain-obj@1.1.0", "", {}, "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg=="], + "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], "minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], @@ -2357,6 +2526,16 @@ "mongodb-connection-string-url/whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="], + "multicodec/uint8arrays": ["uint8arrays@3.1.1", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg=="], + + "multihashes/uint8arrays": ["uint8arrays@3.1.1", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg=="], + + "multihashes/varint": ["varint@5.0.2", "", {}, "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="], + + "multihashing-async/err-code": ["err-code@3.0.1", "", {}, "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA=="], + + "multihashing-async/uint8arrays": ["uint8arrays@3.1.1", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg=="], + "node-plop/globby": ["globby@13.2.2", "", { "dependencies": { "dir-glob": "^3.0.1", "fast-glob": "^3.3.0", "ignore": "^5.2.4", "merge2": "^1.4.1", "slash": "^4.0.0" } }, "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w=="], "node-plop/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], @@ -2369,11 +2548,9 @@ "ora/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], - "ox/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], - - "param-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "ox/@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.0", "", {}, "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg=="], - "pascal-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "ox/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], "patch-package/cross-spawn": ["cross-spawn@6.0.6", "", { "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw=="], @@ -2383,19 +2560,25 @@ "patch-package/yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="], - "path-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "plop/chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], "protobufjs/@types/node": ["@types/node@22.7.5", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ=="], "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], + "read-pkg/normalize-package-data": ["normalize-package-data@2.5.0", "", { "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA=="], + + "read-pkg/type-fest": ["type-fest@0.6.0", "", {}, "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg=="], + + "read-pkg-up/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + + "read-pkg-up/type-fest": ["type-fest@0.8.1", "", {}, "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="], + "resolve-dir/global-modules": ["global-modules@1.0.0", "", { "dependencies": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", "resolve-dir": "^1.0.0" } }, "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg=="], "restore-cursor/onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], - "rimraf/glob": ["glob@7.1.7", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ=="], + "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], "rpc-websockets/@types/ws": ["@types/ws@8.5.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w=="], @@ -2403,8 +2586,6 @@ "rpc-websockets/ws": ["ws@8.18.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w=="], - "rxjs/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "safe-array-concat/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], "safe-push-apply/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], @@ -2425,16 +2606,12 @@ "secp256k1/node-addon-api": ["node-addon-api@5.1.0", "", {}, "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="], - "sentence-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "shelljs/glob": ["glob@7.1.7", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ=="], + "shelljs/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], "shelljs/interpret": ["interpret@1.4.0", "", {}, "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="], "shelljs/rechoir": ["rechoir@0.6.2", "", { "dependencies": { "resolve": "^1.1.6" } }, "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw=="], - "snake-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "solc/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], "solc/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="], @@ -2467,7 +2644,7 @@ "ts-generator/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], - "ts-generator/glob": ["glob@7.1.7", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ=="], + "ts-generator/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], "ts-generator/ts-essentials": ["ts-essentials@1.0.4", "", {}, "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ=="], @@ -2507,6 +2684,8 @@ "web3-eth-contract/web3-utils": ["web3-utils@4.3.3", "", { "dependencies": { "ethereum-cryptography": "^2.0.0", "eventemitter3": "^5.0.1", "web3-errors": "^1.3.1", "web3-types": "^1.10.0", "web3-validator": "^2.0.6" } }, "sha512-kZUeCwaQm+RNc2Bf1V3BYbF29lQQKz28L0y+FA4G0lS8IxtJVGi5SeDTUkpwqqkdHHC7JcapPDnyyzJ1lfWlOw=="], + "web3-eth-ens/@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.0", "", {}, "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg=="], + "web3-eth-ens/web3-utils": ["web3-utils@4.3.3", "", { "dependencies": { "ethereum-cryptography": "^2.0.0", "eventemitter3": "^5.0.1", "web3-errors": "^1.3.1", "web3-types": "^1.10.0", "web3-validator": "^2.0.6" } }, "sha512-kZUeCwaQm+RNc2Bf1V3BYbF29lQQKz28L0y+FA4G0lS8IxtJVGi5SeDTUkpwqqkdHHC7JcapPDnyyzJ1lfWlOw=="], "web3-eth-iban/web3-utils": ["web3-utils@4.3.3", "", { "dependencies": { "ethereum-cryptography": "^2.0.0", "eventemitter3": "^5.0.1", "web3-errors": "^1.3.1", "web3-types": "^1.10.0", "web3-validator": "^2.0.6" } }, "sha512-kZUeCwaQm+RNc2Bf1V3BYbF29lQQKz28L0y+FA4G0lS8IxtJVGi5SeDTUkpwqqkdHHC7JcapPDnyyzJ1lfWlOw=="], @@ -2527,7 +2706,7 @@ "web3-providers-ws/web3-utils": ["web3-utils@4.3.3", "", { "dependencies": { "ethereum-cryptography": "^2.0.0", "eventemitter3": "^5.0.1", "web3-errors": "^1.3.1", "web3-types": "^1.10.0", "web3-validator": "^2.0.6" } }, "sha512-kZUeCwaQm+RNc2Bf1V3BYbF29lQQKz28L0y+FA4G0lS8IxtJVGi5SeDTUkpwqqkdHHC7JcapPDnyyzJ1lfWlOw=="], - "web3-providers-ws/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], + "web3-providers-ws/ws": ["ws@8.18.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w=="], "web3-rpc-providers/web3-utils": ["web3-utils@4.3.3", "", { "dependencies": { "ethereum-cryptography": "^2.0.0", "eventemitter3": "^5.0.1", "web3-errors": "^1.3.1", "web3-types": "^1.10.0", "web3-validator": "^2.0.6" } }, "sha512-kZUeCwaQm+RNc2Bf1V3BYbF29lQQKz28L0y+FA4G0lS8IxtJVGi5SeDTUkpwqqkdHHC7JcapPDnyyzJ1lfWlOw=="], @@ -2549,6 +2728,20 @@ "xtend/object-keys": ["object-keys@0.4.0", "", {}, "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw=="], + "@cowprotocol/app-data/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "@ethereumjs/common/@ethereumjs/util/@ethereumjs/rlp": ["@ethereumjs/rlp@4.0.1", "", { "bin": { "rlp": "bin/rlp" } }, "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw=="], + + "@ethereumjs/common/@ethereumjs/util/ethereum-cryptography": ["ethereum-cryptography@2.2.1", "", { "dependencies": { "@noble/curves": "1.4.2", "@noble/hashes": "1.4.0", "@scure/bip32": "1.4.0", "@scure/bip39": "1.3.0" } }, "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg=="], + + "@ethereumjs/tx/ethereum-cryptography/@noble/curves": ["@noble/curves@1.4.2", "", { "dependencies": { "@noble/hashes": "1.4.0" } }, "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw=="], + + "@ethereumjs/tx/ethereum-cryptography/@noble/hashes": ["@noble/hashes@1.4.0", "", {}, "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg=="], + + "@ethereumjs/tx/ethereum-cryptography/@scure/bip32": ["@scure/bip32@1.4.0", "", { "dependencies": { "@noble/curves": "~1.4.0", "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" } }, "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg=="], + + "@ethereumjs/tx/ethereum-cryptography/@scure/bip39": ["@scure/bip39@1.3.0", "", { "dependencies": { "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" } }, "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ=="], + "@ethereumjs/util/ethereum-cryptography/@noble/curves": ["@noble/curves@1.4.2", "", { "dependencies": { "@noble/hashes": "1.4.0" } }, "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw=="], "@ethereumjs/util/ethereum-cryptography/@noble/hashes": ["@noble/hashes@1.4.0", "", {}, "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg=="], @@ -2579,6 +2772,14 @@ "@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], + "@openzeppelin/merkle-tree/ethereum-cryptography/@noble/curves": ["@noble/curves@1.9.0", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg=="], + + "@openzeppelin/merkle-tree/ethereum-cryptography/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + + "@openzeppelin/merkle-tree/ethereum-cryptography/@scure/bip32": ["@scure/bip32@1.7.0", "", { "dependencies": { "@noble/curves": "~1.9.0", "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw=="], + + "@openzeppelin/merkle-tree/ethereum-cryptography/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], + "@sentry/node/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@5.62.0", "", {}, "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ=="], @@ -2615,7 +2816,7 @@ "deferred-leveldown/abstract-leveldown/xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], - "del/rimraf/glob": ["glob@7.1.7", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ=="], + "del/rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], "escodegen/optionator/levn": ["levn@0.3.0", "", { "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA=="], @@ -2623,6 +2824,8 @@ "escodegen/optionator/type-check": ["type-check@0.3.2", "", { "dependencies": { "prelude-ls": "~1.1.2" } }, "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg=="], + "eslint/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="], + "ethereum-cryptography/@scure/bip32/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="], "ethereum-cryptography/@scure/bip39/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="], @@ -2631,7 +2834,7 @@ "ethereumjs-abi/ethereumjs-util/ethereum-cryptography": ["ethereum-cryptography@0.1.3", "", { "dependencies": { "@types/pbkdf2": "^3.0.0", "@types/secp256k1": "^4.0.1", "blakejs": "^1.1.0", "browserify-aes": "^1.2.0", "bs58check": "^2.1.2", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "hash.js": "^1.1.7", "keccak": "^3.0.0", "pbkdf2": "^3.0.17", "randombytes": "^2.1.0", "safe-buffer": "^5.1.2", "scrypt-js": "^3.0.0", "secp256k1": "^4.0.1", "setimmediate": "^1.0.5" } }, "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ=="], - "flat-cache/rimraf/glob": ["glob@7.1.7", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ=="], + "flat-cache/rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], "gaxios/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], @@ -2703,6 +2906,12 @@ "patch-package/cross-spawn/which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "./bin/which" } }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="], + "read-pkg-up/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + + "read-pkg/normalize-package-data/hosted-git-info": ["hosted-git-info@2.8.9", "", {}, "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="], + + "read-pkg/normalize-package-data/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="], + "resolve-dir/global-modules/global-prefix": ["global-prefix@1.0.2", "", { "dependencies": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" } }, "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg=="], "restore-cursor/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], @@ -2833,6 +3042,18 @@ "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], + "@ethereumjs/common/@ethereumjs/util/ethereum-cryptography/@noble/curves": ["@noble/curves@1.4.2", "", { "dependencies": { "@noble/hashes": "1.4.0" } }, "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw=="], + + "@ethereumjs/common/@ethereumjs/util/ethereum-cryptography/@noble/hashes": ["@noble/hashes@1.4.0", "", {}, "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg=="], + + "@ethereumjs/common/@ethereumjs/util/ethereum-cryptography/@scure/bip32": ["@scure/bip32@1.4.0", "", { "dependencies": { "@noble/curves": "~1.4.0", "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" } }, "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg=="], + + "@ethereumjs/common/@ethereumjs/util/ethereum-cryptography/@scure/bip39": ["@scure/bip39@1.3.0", "", { "dependencies": { "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" } }, "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ=="], + + "@ethereumjs/tx/ethereum-cryptography/@scure/bip32/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="], + + "@ethereumjs/tx/ethereum-cryptography/@scure/bip39/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="], + "@ethereumjs/util/ethereum-cryptography/@scure/bip32/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="], "@ethereumjs/util/ethereum-cryptography/@scure/bip39/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="], @@ -2865,6 +3086,8 @@ "patch-package/cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + "read-pkg-up/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + "resolve-dir/global-modules/global-prefix/which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "./bin/which" } }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="], "solhint/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], @@ -3003,6 +3226,10 @@ "web3/web3-utils/ethereum-cryptography/@scure/bip39": ["@scure/bip39@1.3.0", "", { "dependencies": { "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" } }, "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ=="], + "@ethereumjs/common/@ethereumjs/util/ethereum-cryptography/@scure/bip32/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="], + + "@ethereumjs/common/@ethereumjs/util/ethereum-cryptography/@scure/bip39/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="], + "@grpc/grpc-js/@grpc/proto-loader/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "command-line-usage/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], @@ -3011,6 +3238,8 @@ "inquirer/cli-cursor/restore-cursor/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + "read-pkg-up/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + "resolve-dir/global-modules/global-prefix/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "solidity-coverage/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], diff --git a/deployments/_deployments_log_file.json b/deployments/_deployments_log_file.json index fd1073587..cce49c8df 100644 --- a/deployments/_deployments_log_file.json +++ b/deployments/_deployments_log_file.json @@ -30339,9 +30339,9 @@ ], "1.1.0": [ { - "ADDRESS": "0x08BfAc22A3B41637edB8A7920754fDb30B18f740", + "ADDRESS": "0xF336cc028Fc5328472f96e377d32Fd32F8eE1750", "OPTIMIZER_RUNS": "1000000", - "TIMESTAMP": "2024-12-31 12:23:04", + "TIMESTAMP": "2025-05-27 13:50:22", "CONSTRUCTOR_ARGS": "0x000000000000000000000000e35e9842fceaca96570b734083f4a58e8f7c5f2a00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1", "SALT": "", "VERIFIED": "true" @@ -32870,9 +32870,9 @@ "staging": { "1.0.0": [ { - "ADDRESS": "0x3cf7dE0e31e13C93c8Aada774ADF1C7eD58157f5", + "ADDRESS": "0x681a3409c35F12224c436D50Ce14F25f954B6Ea2", "OPTIMIZER_RUNS": "1000000", - "TIMESTAMP": "2024-11-07 14:15:11", + "TIMESTAMP": "2025-05-23 17:41:51", "CONSTRUCTOR_ARGS": "0x000000000000000000000000a5f565650890fba1824ee0f21ebbbf660a179934000000000000000000000000f70da97812cb96acdf810712aa562db8dfa3dbef", "SALT": "", "VERIFIED": "true" @@ -33830,5 +33830,51 @@ ] } } + }, + "WhitelistManagerFacet": { + "arbitrum": { + "staging": { + "1.0.3": [ + { + "ADDRESS": "0x603f0c31B37E5ca3eA75D5730CCfaBCFF6D17aa3", + "OPTIMIZER_RUNS": "1000000", + "TIMESTAMP": "2025-05-16 14:32:49", + "CONSTRUCTOR_ARGS": "0x", + "SALT": "", + "VERIFIED": "true" + } + ] + } + } + }, + "Patcher": { + "arbitrum": { + "staging": { + "1.0.0": [ + { + "ADDRESS": "0x18069208cA7c2D55aa0073E047dD45587B26F6D4", + "OPTIMIZER_RUNS": "1000000", + "TIMESTAMP": "2025-06-04 12:55:52", + "CONSTRUCTOR_ARGS": "0x", + "SALT": "", + "VERIFIED": "true" + } + ] + } + }, + "base": { + "staging": { + "1.0.0": [ + { + "ADDRESS": "0x18069208cA7c2D55aa0073E047dD45587B26F6D4", + "OPTIMIZER_RUNS": "1000000", + "TIMESTAMP": "2025-06-03 16:39:25", + "CONSTRUCTOR_ARGS": "0x", + "SALT": "", + "VERIFIED": "true" + } + ] + } + } } } diff --git a/deployments/arbitrum.diamond.staging.json b/deployments/arbitrum.diamond.staging.json index 070c78151..f61031a8e 100644 --- a/deployments/arbitrum.diamond.staging.json +++ b/deployments/arbitrum.diamond.staging.json @@ -173,7 +173,8 @@ "ReceiverChainflip": "", "ReceiverStargateV2": "", "RelayerCelerIM": "0xa1Ed8783AC96385482092b82eb952153998e9b70", - "TokenWrapper": "0xF63b27AE2Dc887b88f82E2Cc597d07fBB2E78E70" + "TokenWrapper": "0xF63b27AE2Dc887b88f82E2Cc597d07fBB2E78E70", + "Patcher": "0x3971A968c03cd9640239C937F8d30D024840E691" } } } diff --git a/deployments/arbitrum.staging.json b/deployments/arbitrum.staging.json index c1b95c940..346e89ccd 100644 --- a/deployments/arbitrum.staging.json +++ b/deployments/arbitrum.staging.json @@ -47,11 +47,13 @@ "TokenWrapper": "0xF63b27AE2Dc887b88f82E2Cc597d07fBB2E78E70", "EmergencyPauseFacet": "0x17Bb203F42d8e404ac7E8dB6ff972B7E8473850b", "Permit2Proxy": "0x6FC01BC9Ff6Cdab694Ec8Ca41B21a2F04C8c37E5", - "AcrossFacetV3": "0x08BfAc22A3B41637edB8A7920754fDb30B18f740", + "AcrossFacetV3": "0xF336cc028Fc5328472f96e377d32Fd32F8eE1750", "ReceiverAcrossV3": "0xe4F3DEF14D61e47c696374453CD64d438FD277F8", "AcrossFacetPackedV3": "0x21767081Ff52CE5563A29f27149D01C7127775A2", - "RelayFacet": "0x3cf7dE0e31e13C93c8Aada774ADF1C7eD58157f5", + "RelayFacet": "0x681a3409c35F12224c436D50Ce14F25f954B6Ea2", "GlacisFacet": "0xF82830B952Bc60b93206FA22f1cD4770cedb2840", "GasZipFacet": "0x37f3F3E9d909fB1163448C511193b8481e541C62", - "ChainflipFacet": "0xa884c21873A671bD010567cf97c937b153F842Cc" -} \ No newline at end of file + "ChainflipFacet": "0xa884c21873A671bD010567cf97c937b153F842Cc", + "Patcher": "0x18069208cA7c2D55aa0073E047dD45587B26F6D4", + "WhitelistManagerFacet": "0x603f0c31B37E5ca3eA75D5730CCfaBCFF6D17aa3" +} diff --git a/deployments/base.staging.json b/deployments/base.staging.json index fd7b21858..5bd2aa114 100644 --- a/deployments/base.staging.json +++ b/deployments/base.staging.json @@ -1,3 +1,4 @@ { - "StandardizedCallFacet": "0x637Ac9AddC9C38b3F52878E11620a9060DC71d8B" + "StandardizedCallFacet": "0x637Ac9AddC9C38b3F52878E11620a9060DC71d8B", + "Patcher": "0x18069208cA7c2D55aa0073E047dD45587B26F6D4" } \ No newline at end of file diff --git a/docs/Patcher.md b/docs/Patcher.md new file mode 100644 index 000000000..1eef68dba --- /dev/null +++ b/docs/Patcher.md @@ -0,0 +1,163 @@ +# Patcher + +## Description + +The Patcher is a utility contract that enables dynamic calldata patching before execution. It allows you to retrieve values dynamically from external contracts and use them to patch specific positions in calldata before executing the final call. This is particularly useful for scenarios where exact amounts are only known at execution time, such as token balances after deposits or bridge transfers. + +## How it works + +The Patcher works by: +1. Retrieving dynamic values from external contracts via static calls +2. Patching these values into predetermined positions in calldata +3. Executing the final call with the patched data + +```mermaid +graph LR; + A[User] --> B[Patcher Contract] + B --> C[Value Source Contract] + C --> B + B --> D[Final Target Contract] + B --> E[Patch Calldata] + E --> D +``` + +## Public Methods + +### Single Value Patching + +- `function executeWithDynamicPatches(address valueSource, bytes calldata valueGetter, address finalTarget, uint256 value, bytes calldata data, uint256[] calldata offsets, bool delegateCall)` + - Retrieves a single dynamic value and patches it into multiple positions in the calldata before execution + +### Token Deposit with Single Value Patching + +- `function depositAndExecuteWithDynamicPatches(address tokenAddress, address valueSource, bytes calldata valueGetter, address finalTarget, uint256 value, bytes calldata data, uint256[] calldata offsets, bool delegateCall)` + - Transfers the caller's entire token balance to the Patcher, approves the final target, then executes with dynamic patching + +### Multiple Value Patching + +- `function executeWithMultiplePatches(address[] calldata valueSources, bytes[] calldata valueGetters, address finalTarget, uint256 value, bytes calldata data, uint256[][] calldata offsetGroups, bool delegateCall)` + - Retrieves multiple dynamic values from different sources and patches them into different positions in the calldata + +### Token Deposit with Multiple Value Patching + +- `function depositAndExecuteWithMultiplePatches(address tokenAddress, address[] calldata valueSources, bytes[] calldata valueGetters, address finalTarget, uint256 value, bytes calldata data, uint256[][] calldata offsetGroups, bool delegateCall)` + - Transfers the caller's entire token balance to the Patcher, approves the final target, then executes with multiple dynamic patches + +## Parameters + +### Common Parameters + +- `valueSource` / `valueSources`: The contract(s) to query for dynamic values +- `valueGetter` / `valueGetters`: The calldata to use for retrieving the dynamic value(s) (e.g., `balanceOf(address)` call) +- `finalTarget`: The contract to call with the patched data +- `value`: The ETH value to send with the final call +- `data`: The original calldata to patch and execute +- `offsets` / `offsetGroups`: Byte offset(s) in the calldata where the dynamic value(s) should be written +- `delegateCall`: Whether to use delegatecall instead of a regular call for the final execution +- `tokenAddress`: The ERC20 token to transfer from the caller (for deposit methods) + +### Offset Calculation + +Offsets specify the exact byte position in the calldata where a 32-byte value should be written. These are typically calculated by: +1. Encoding the target function call with placeholder values +2. Finding the byte position of the placeholder in the encoded data +3. Using that position as the offset + +## Use Cases + +### Cross-Chain Bridge with Destination Swap + +The Patcher is particularly useful for cross-chain scenarios where the exact amount received from a bridge is unknown until execution: + +1. **Bridge tokens** from source chain to destination chain +2. **Receive variable amount** due to fees, slippage, or exchange rates +3. **Use Patcher** to query the actual received balance +4. **Patch the balance** into a swap call to use the exact amount received +5. **Execute the swap** with the correct amount + +### Dynamic Balance Swaps + +When you need to swap the entire balance of a token but don't know the exact amount: + +1. **Deposit tokens** to the Patcher contract +2. **Query the balance** dynamically +3. **Patch the balance** into a DEX swap call +4. **Execute the swap** using the entire deposited amount + +### Oracle-Based Transactions + +For transactions that depend on real-time data: + +1. **Query price oracles** or other data sources +2. **Patch the values** into transaction parameters +3. **Execute** with up-to-date information + +## Error Handling + +The Patcher includes several error types for different failure scenarios: + +- `FailedToGetDynamicValue()`: Thrown when the static call to retrieve a dynamic value fails +- `MismatchedArrayLengths()`: Thrown when input arrays have different lengths in multiple patch methods +- `InvalidPatchOffset()`: Thrown when a patch offset would write beyond the calldata bounds + +## Security Considerations + +- The Patcher uses `staticcall` to retrieve dynamic values, ensuring no state changes during value retrieval +- Offset validation prevents writing beyond calldata boundaries +- The contract is designed to be used with delegate calls for integration into larger systems +- Token approvals are given to the final target contract, not stored permanently + +## Integration Patterns + +### With Bridge Receivers + +The Patcher is commonly used in bridge receiver contracts to handle variable bridge amounts: + +```solidity +// Pseudo-code example +function handleBridgeMessage(bytes calldata message) external { + // Decode swap parameters from message + SwapData memory swapData = abi.decode(message, (SwapData)); + + // Use Patcher to deposit received tokens and execute swap with exact balance + patcher.depositAndExecuteWithDynamicPatches( + bridgedToken, + bridgedToken, // value source + abi.encodeCall(IERC20.balanceOf, (address(patcher))), // value getter + dexAggregator, // final target + 0, // no ETH value + swapCalldata, // calldata with placeholder amount + [amountOffset], // where to patch the amount + false // regular call + ); +} +``` + +### With DEX Aggregators + +For swapping entire token balances through DEX aggregators: + +```solidity +// Pseudo-code example +function swapEntireBalance(address token, bytes calldata swapCalldata, uint256 amountOffset) external { + patcher.depositAndExecuteWithDynamicPatches( + token, + token, // query token balance + abi.encodeCall(IERC20.balanceOf, (address(patcher))), + dexAggregator, + 0, + swapCalldata, + [amountOffset], + false + ); +} +``` + +## Best Practices + +1. **Calculate offsets carefully**: Ensure offsets point to the correct parameter positions in the calldata +2. **Use appropriate value getters**: Choose the right function to call for retrieving dynamic values +3. **Handle failures gracefully**: The Patcher will revert if value retrieval fails +4. **Consider gas costs**: Multiple patches and complex calls increase gas usage +5. **Test thoroughly**: Dynamic patching can be complex - test with various scenarios +6. **Validate inputs**: Ensure array lengths match for multiple patch operations \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 1ede9f3f7..8974cac85 100644 --- a/docs/README.md +++ b/docs/README.md @@ -57,6 +57,7 @@ - [Executor](./Executor.md) - [FeeCollector](./FeeCollector.md) - [LiFuelFeeCollector](./LiFuelFeeCollector.md) +- [Patcher](./Patcher.md) - [Receiver](./Receiver.md) - [ReceiverStargateV2](./ReceiverStargateV2.md) - [ReceiverChainflip](./ReceiverChainflip.md) diff --git a/package.json b/package.json index e24702bdb..503ba1c4a 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ }, "dependencies": { "@arbitrum/sdk": "^3.0.0", + "@cowprotocol/cow-sdk": "^5.10.3", "@hop-protocol/sdk": "0.0.1-beta.310", "@layerzerolabs/lz-v2-utilities": "^2.3.21", "@ledgerhq/hw-app-eth": "^6.43.0", diff --git a/script/demoScripts/demoPatcher.ts b/script/demoScripts/demoPatcher.ts new file mode 100644 index 000000000..cafdada8b --- /dev/null +++ b/script/demoScripts/demoPatcher.ts @@ -0,0 +1,220 @@ +#!/usr/bin/env bun + +import { + parseUnits, + createWalletClient, + http, + getContract, + Hex, + getAddress, +} from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { arbitrum } from 'viem/chains' +import { ethers } from 'ethers' +import { SupportedChainId, OrderKind, TradingSdk } from '@cowprotocol/cow-sdk' +import { defineCommand, runMain } from 'citty' +import { consola } from 'consola' +import erc20Artifact from '../../out/ERC20/ERC20.sol/ERC20.json' +import { setupCowShedPostHooks } from './utils/cowSwapHelpers' + +const ARBITRUM_WETH = '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1' +const ARBITRUM_USDC = '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' +const BASE_USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' +import arbitrumDeployments from '../../deployments/arbitrum.staging.json' +const LIFI_DIAMOND_ARBITRUM = arbitrumDeployments.LiFiDiamond +const PATCHER_ARBITRUM = arbitrumDeployments.Patcher +const VAULT_RELAYER_ARBITRUM = '0xC92E8bdf79f0507f65a392b0ab4667716BFE0110' + +const ERC20_ABI = erc20Artifact.abi + +/** + * Execute CowSwap demo with Patcher contract + * + * Example successful transaction: + * - Arbitrum: https://arbiscan.io/tx/0x7536cd0d5175a6a985f6a0c5cbfaf63b573fe2300301c57e12cca4c8995fe891 + */ +async function executeCowSwapDemo(options: { + privateKey: string + dryRun: boolean +}) { + // Set up wallet client + const account = privateKeyToAccount(options.privateKey as Hex) + const walletClient = createWalletClient({ + chain: arbitrum, + transport: http(), + account, + }) + + const walletAddress = account.address + consola.info(`Connected wallet: ${walletAddress}`) + + // Amount to swap: 0.001 WETH + const swapAmount = parseUnits('0.001', 18) + consola.info(`Swap amount: 0.001 WETH`) + + // Check WETH balance and approve if needed + const wethContract = getContract({ + address: ARBITRUM_WETH as Hex, + abi: ERC20_ABI, + client: { public: walletClient, wallet: walletClient }, + }) + + const wethBalance = (await wethContract.read.balanceOf([ + walletAddress, + ])) as bigint + consola.info(`WETH balance: ${wethBalance}`) + + if (wethBalance < swapAmount) { + consola.error(`Insufficient WETH balance. Need at least 0.001 WETH.`) + process.exit(1) + } + + // Check allowance + const allowance = (await wethContract.read.allowance([ + walletAddress, + VAULT_RELAYER_ARBITRUM, + ])) as bigint + consola.info(`Current allowance: ${allowance}`) + + if (allowance < swapAmount) { + consola.info('Approving WETH for CoW Protocol VaultRelayer...') + if (!options.dryRun) { + const approveTx = await wethContract.write.approve([ + VAULT_RELAYER_ARBITRUM as `0x${string}`, + BigInt( + '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + ), // Max uint256 + ]) + consola.success(`Approval transaction sent: ${approveTx}`) + } else { + consola.info(`[DRY RUN] Would approve WETH for VaultRelayer`) + } + } + + // Set up CowShed post hooks + const { shedDeterministicAddress, postHooks } = await setupCowShedPostHooks({ + chainId: 42161, // Arbitrum chain ID + walletClient, + usdcAddress: ARBITRUM_USDC, + receivedAmount: parseUnits('0', 6), // This will be dynamically patched + lifiDiamondAddress: LIFI_DIAMOND_ARBITRUM, + patcherAddress: PATCHER_ARBITRUM, + baseUsdcAddress: BASE_USDC, + destinationChainId: 8453n, // BASE chain ID + }) + + // Create ethers provider and signer for CoW SDK + const provider = new ethers.providers.JsonRpcProvider( + arbitrum.rpcUrls.default.http[0] + ) + const ethersSigner = new ethers.Wallet(options.privateKey, provider) + + // Initialize CoW SDK with proper TraderParameters + const cowSdk = new TradingSdk({ + chainId: SupportedChainId.ARBITRUM_ONE, + signer: ethersSigner, + appCode: 'lifi-demo' as any, // Cast to any to satisfy the AppCode type + }) + + // Create the order parameters + const parameters = { + kind: OrderKind.SELL, + sellToken: getAddress(ARBITRUM_WETH), + sellTokenDecimals: 18, + buyToken: getAddress(ARBITRUM_USDC), + buyTokenDecimals: 6, + amount: swapAmount.toString(), + receiver: getAddress(shedDeterministicAddress), // Important: Set the receiver to the CowShed proxy + validFor: 30 * 60, // 30 minutes in seconds + slippageBps: 50, // 0.5% slippage + } + + // Create advanced settings with post hooks + const advancedSettings = { + appData: { + metadata: { + hooks: { + version: '1', + pre: [], + post: postHooks, + }, + }, + }, + } + + // Submit the order with post hooks + if (!options.dryRun) { + consola.info('Submitting order to CowSwap...') + try { + // Create an AbortController for proper cancellation + const abortController = new AbortController() + const timeoutId = setTimeout(() => { + abortController.abort() + }, 30000) + + try { + const orderId = await cowSdk.postSwapOrder(parameters, advancedSettings) + clearTimeout(timeoutId) + + consola.success(`Order created with hash: ${orderId}`) + consola.info( + `Explorer URL: https://explorer.cow.fi/orders/${orderId}?chainId=42161` + ) + } catch (error) { + clearTimeout(timeoutId) + if (abortController.signal.aborted) { + throw new Error('Order submission timed out after 30 seconds') + } + throw error + } + } catch (error) { + consola.error('Error submitting order to CowSwap:', error) + throw error + } + } else { + consola.info(`[DRY RUN] Would submit order to CowSwap with post hooks`) + consola.info(`Parameters: ${JSON.stringify(parameters, null, 2)}`) + consola.info(`Post hooks: ${JSON.stringify(postHooks, null, 2)}`) + } + + consola.success('CowSwap demo completed successfully') +} + +/** + * Main function to execute the demo + */ +async function main(options: { privateKey: string; dryRun: boolean }) { + try { + consola.start('Starting CowSwap with Patcher demo') + await executeCowSwapDemo(options) + } catch (error) { + consola.error('Error executing demo:', error) + process.exit(1) + } +} + +// CLI command definition +const cmd = defineCommand({ + meta: { + name: 'demoPatcher', + description: 'Demo script for CowSwap with Patcher contract', + }, + args: { + privateKey: { + type: 'string', + description: 'Private key for the wallet', + required: true, + }, + dryRun: { + type: 'boolean', + description: 'Run in dry-run mode without submitting transactions', + default: false, + }, + }, + run: async ({ args }) => { + await main(args) + }, +}) + +// Run the command +runMain(cmd) diff --git a/script/demoScripts/demoPatcherDest.ts b/script/demoScripts/demoPatcherDest.ts new file mode 100644 index 000000000..9d1616277 --- /dev/null +++ b/script/demoScripts/demoPatcherDest.ts @@ -0,0 +1,628 @@ +import { defineCommand, runMain } from 'citty' +import { consola } from 'consola' +import { randomBytes } from 'crypto' +import { + createWalletClient, + createPublicClient, + http, + parseUnits, + getContract, + type Hex, + encodeFunctionData, + encodeAbiParameters, + parseAbi, + getAddress, +} from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { arbitrum } from 'viem/chains' +import baseDeployments from '../../deployments/base.json' +import baseStagingDeployments from '../../deployments/base.staging.json' +import arbitrumStagingDeployments from '../../deployments/arbitrum.staging.json' +import { + generateNeedle, + findNeedleOffset, + generateExecuteWithDynamicPatchesCalldata, + generateBalanceOfCalldata, +} from './utils/patcherHelpers' + +/** + * Example successful transactions: + * - Source (Arbitrum): https://arbiscan.io/tx/0xf14f9897c01ac30a1b8c13fb7b3e6f840f312a9212f651f730e999940871db56 + * - Destination (Base): https://basescan.org/tx/0x6835a3bd73051870bb8f100c2267b7143905011b6e4028d80e7154ff6d307fdc + */ + +// Contract addresses +const ARBITRUM_WETH = '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1' +const BASE_WETH = '0x4200000000000000000000000000000000000006' +const BASE_USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' +const BASE_LIFI_DEX_AGGREGATOR = '0x9Caab1750104147c9872772b3d0bE3D4290e1e86' // LiFiDEXAggregator on Base +const BASE_EXECUTOR = baseDeployments.Executor as Hex +const BASE_PATCHER = baseStagingDeployments.Patcher as Hex +const RECEIVER_ACROSS_V3_BASE = baseDeployments.ReceiverAcrossV3 as Hex +const LIFI_DIAMOND_ARBITRUM = arbitrumStagingDeployments.LiFiDiamond as Hex + +// Simple ERC20 ABI - Human readable format +const ERC20_ABI = parseAbi([ + 'function allowance(address owner, address spender) view returns (uint256)', + 'function approve(address spender, uint256 amount) returns (bool)', + 'function balanceOf(address account) view returns (uint256)', +]) + +/** + * Fetch cross-chain route with destination swap using LiFi Advanced Routes API + */ +async function fetchCrossChainRoute( + fromAmount: string, + fromAddress: string +): Promise { + const requestBody = { + fromAddress, + fromAmount, + fromChainId: 42161, // Arbitrum + fromTokenAddress: ARBITRUM_WETH, // WETH on Arbitrum + toChainId: 8453, // Base + toTokenAddress: BASE_USDC, // USDC on Base + options: { + integrator: 'lifi-demo', + order: 'CHEAPEST', + slippage: 0.05, // 5% slippage + maxPriceImpact: 0.4, + allowSwitchChain: true, + bridges: { + deny: [ + 'hop', + 'cbridge', + 'optimism', + 'gnosis', + 'omni', + 'celercircle', + 'thorswap', + 'symbiosis', + 'mayan', + 'mayanWH', + 'mayanMCTP', + 'allbridge', + 'celerim', + 'squid', + 'relay', + 'polygon', + 'arbitrum', + 'glacis', + ], + }, + exchanges: { + allow: ['lifidexaggregator'], + }, + }, + } + + try { + consola.info('Fetching cross-chain route from LiFi Advanced Routes API...') + const response = await fetch( + 'https://api.jumper.exchange/p/lifi/advanced/routes', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(requestBody), + } + ) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const data = await response.json() + + if (!data.routes || data.routes.length === 0) { + throw new Error('No routes found') + } + + const route = data.routes[0] // Use the first (cheapest) route + consola.success( + `Found route: ${route.fromAmount} WETH → ${route.toAmount} USDC` + ) + consola.info(`Route ID: ${route.id}`) + consola.info(`Gas cost: $${route.gasCostUSD}`) + consola.info(`Steps: ${route.steps.length}`) + + // Log step details + route.steps.forEach((step: any, index: number) => { + consola.info(`Step ${index + 1}: ${step.tool} (${step.type})`) + if (step.action.fromToken && step.action.toToken) { + consola.info( + ` ${step.action.fromToken.symbol} → ${step.action.toToken.symbol}` + ) + } + }) + + return route + } catch (error) { + consola.error('Error fetching cross-chain route:', error) + throw error + } +} + +/** + * Extract bridge and swap details from LiFi route + */ +function extractRouteDetails(route: any) { + const bridgeStep = route.steps.find( + (step: any) => + step.type === 'lifi' && + step.includedSteps?.some((s: any) => s.type === 'cross') + ) + + if (!bridgeStep) { + throw new Error('No bridge step found in route') + } + + const crossStep = bridgeStep.includedSteps.find( + (s: any) => s.type === 'cross' + ) + const destSwapStep = bridgeStep.includedSteps.find( + (s: any) => s.type === 'swap' + ) + + if (!crossStep) { + throw new Error('No cross-chain step found') + } + + consola.info('📊 Route Analysis:') + consola.info( + `- Bridge: ${crossStep.action.fromToken.symbol} → ${crossStep.action.toToken.symbol}` + ) + consola.info(`- Bridge amount: ${crossStep.action.fromAmount}`) + consola.info(`- Expected received: ${crossStep.estimate.toAmount}`) + + if (destSwapStep) { + consola.info( + `- Destination swap: ${destSwapStep.action.fromToken.symbol} → ${destSwapStep.action.toToken.symbol}` + ) + consola.info(`- Swap input: ${destSwapStep.action.fromAmount}`) + consola.info(`- Swap output: ${destSwapStep.estimate.toAmount}`) + consola.info(`- Swap min output: ${destSwapStep.estimate.toAmountMin}`) + } + + return { + // Bridge details + fromAmount: crossStep.action.fromAmount, + toAmount: crossStep.estimate.toAmount, + toAmountMin: crossStep.estimate.toAmountMin, + + // Destination swap details (if exists) + hasDestinationSwap: !!destSwapStep, + swapFromAmount: destSwapStep?.action.fromAmount, + swapToAmount: destSwapStep?.estimate.toAmount, + swapToAmountMin: destSwapStep?.estimate.toAmountMin, + + // Final output + finalAmount: route.toAmount, + finalAmountMin: route.toAmountMin, + + // Gas and fees + gasCostUSD: route.gasCostUSD, + + // Tool info + bridgeTool: crossStep.tool, + swapTool: destSwapStep?.tool, + } +} + +/** + * Encode destination call message for ReceiverAcrossV3 using Patcher pattern + */ +function encodeDestinationCallMessage( + transactionId: string, + swapFromAmount: string, + swapToAmountMin: string, + receiver: string +): string { + // Create the value getter for Patcher's WETH balance (after deposit) + const patcherBalanceValueGetter = generateBalanceOfCalldata(BASE_PATCHER) + + // Generate needle for finding the amountIn position + const processRouteAmountNeedle = generateNeedle() + + // Create processRoute calldata with needle + const routeData = + '0x02420000000000000000000000000000000000000601ffff0172ab388e2e2f6facef59e3c3fa2c4e29011c2d38014dac9d1769b9b304cb04741dcdeb2fc14abdf11' as `0x${string}` + + const processRouteCallData = encodeFunctionData({ + abi: parseAbi([ + 'function processRoute(address tokenIn, uint256 amountIn, address tokenOut, uint256 amountOutMin, address to, bytes memory route) payable returns (uint256 amountOut)', + ]), + functionName: 'processRoute', + args: [ + BASE_WETH as `0x${string}`, // tokenIn - WETH on Base + processRouteAmountNeedle as any, // amountIn - needle value (will be patched) + BASE_USDC as `0x${string}`, // tokenOut - USDC on Base + BigInt(swapToAmountMin), // amountOutMin - Minimum USDC out + BASE_EXECUTOR as `0x${string}`, // to - Executor contract on Base + routeData, // route - Route data for WETH->USDC swap + ], + }) + + // Find the processRoute amount offset + const processRouteAmountOffset = findNeedleOffset( + processRouteCallData, + processRouteAmountNeedle + ) + consola.info( + `Found processRoute amountIn offset: ${processRouteAmountOffset} bytes` + ) + + // Generate calldata for depositAndExecuteWithDynamicPatches + const depositAndExecuteCallData = encodeFunctionData({ + abi: parseAbi([ + 'function depositAndExecuteWithDynamicPatches(address tokenAddress, address valueSource, bytes calldata valueGetter, address finalTarget, uint256 value, bytes calldata data, uint256[] calldata offsets, bool delegateCall) returns (bool success, bytes memory returnData)', + ]), + functionName: 'depositAndExecuteWithDynamicPatches', + args: [ + BASE_WETH as `0x${string}`, // tokenAddress - WETH contract + BASE_WETH as `0x${string}`, // valueSource - WETH contract + patcherBalanceValueGetter, // valueGetter - balanceOf(Patcher) call + BASE_LIFI_DEX_AGGREGATOR as `0x${string}`, // finalTarget - LiFiDEXAggregator + 0n, // value - no ETH being sent + processRouteCallData as `0x${string}`, // data - processRoute call + [processRouteAmountOffset], // offsets - position of amountIn parameter + false, // delegateCall - false for regular call + ], + }) + + // Create LibSwap.SwapData structure with single patcher call + const swapData = [ + // Single call: Patcher deposits WETH from Executor, approves LiFiDexAggregator, and executes swap + { + callTo: getAddress(BASE_PATCHER), + approveTo: getAddress(BASE_PATCHER), + sendingAssetId: getAddress(BASE_WETH), + receivingAssetId: getAddress(BASE_USDC), + fromAmount: BigInt(swapFromAmount), + callData: depositAndExecuteCallData as `0x${string}`, + requiresDeposit: true, + }, + ] + + // Encode the message payload for ReceiverAcrossV3.handleV3AcrossMessage + const messagePayload = encodeAbiParameters( + [ + { name: 'transactionId', type: 'bytes32' }, + { + name: 'swapData', + type: 'tuple[]', + components: [ + { name: 'callTo', type: 'address' }, + { name: 'approveTo', type: 'address' }, + { name: 'sendingAssetId', type: 'address' }, + { name: 'receivingAssetId', type: 'address' }, + { name: 'fromAmount', type: 'uint256' }, + { name: 'callData', type: 'bytes' }, + { name: 'requiresDeposit', type: 'bool' }, + ], + }, + { name: 'receiver', type: 'address' }, + ], + [transactionId as `0x${string}`, swapData, receiver as `0x${string}`] + ) + + consola.info( + 'Encoded destination call message using single Patcher deposit call:' + ) + consola.info( + '1. Patcher deposits WETH from Executor, approves LiFiDexAggregator, and executes swap in one call' + ) + return messagePayload +} + +/** + * Construct AcrossV3 bridge transaction calldata using route details + */ +function constructBridgeCallData( + routeDetails: any, + destinationCallMessage: string, + walletAddress: string +): string { + // ABI for startBridgeTokensViaAcrossV3 function - Human readable format + const acrossV3Abi = parseAbi([ + 'function startBridgeTokensViaAcrossV3((bytes32 transactionId, string bridge, string integrator, address referrer, address sendingAssetId, address receiver, uint256 minAmount, uint256 destinationChainId, bool hasSourceSwaps, bool hasDestinationCall) _bridgeData, (address receiverAddress, address refundAddress, address receivingAssetId, uint256 outputAmount, uint64 outputAmountPercent, address exclusiveRelayer, uint32 quoteTimestamp, uint32 fillDeadline, uint32 exclusivityDeadline, bytes message) _acrossData) payable', + ]) + + // Generate a unique transaction ID + const transactionId = `0x${randomBytes(32).toString('hex')}` + + // Bridge data structure + const bridgeData = { + transactionId: transactionId as `0x${string}`, + bridge: 'across', + integrator: 'lifi-demo', + referrer: '0x0000000000000000000000000000000000000000' as `0x${string}`, + sendingAssetId: ARBITRUM_WETH as `0x${string}`, + receiver: RECEIVER_ACROSS_V3_BASE as `0x${string}`, // ReceiverAcrossV3 + minAmount: BigInt(routeDetails.toAmount), // Use same amount as outputAmount for consistency + destinationChainId: 8453n, // Base chain ID + hasSourceSwaps: false, + hasDestinationCall: true, // Enable destination call + } + + // Across data structure - ensure relayer gets meaningful fee + const acrossData = { + receiverAddress: RECEIVER_ACROSS_V3_BASE as `0x${string}`, // ReceiverAcrossV3 + refundAddress: walletAddress as `0x${string}`, + receivingAssetId: BASE_WETH as `0x${string}`, + outputAmount: + (BigInt(routeDetails.toAmount) * BigInt('980000000000000000')) / + BigInt('1000000000000000000'), // 98% of input amount + outputAmountPercent: BigInt('980000000000000000'), // 98% (0.98e18) - 2% fee for relayer to ensure pickup + exclusiveRelayer: + '0x0000000000000000000000000000000000000000' as `0x${string}`, + quoteTimestamp: Math.floor(Date.now() / 1000), // Current timestamp + fillDeadline: Math.floor(Date.now() / 1000) + 7200, // 2 hours from now (more time) + exclusivityDeadline: 0, + message: destinationCallMessage as `0x${string}`, // Our encoded destination call + } + + // Encode the transaction + const callData = encodeFunctionData({ + abi: acrossV3Abi, + functionName: 'startBridgeTokensViaAcrossV3', + args: [bridgeData, acrossData], + }) + + consola.success( + 'Successfully constructed AcrossV3 bridge transaction calldata' + ) + return callData +} + +/** + * Execute cross-chain bridge with destination swap using LiFi Advanced Routes + */ +async function executeCrossChainBridgeWithSwap(options: { + privateKey: string + dryRun: boolean +}) { + // Set up wallet client + const account = privateKeyToAccount(options.privateKey as Hex) + const walletClient = createWalletClient({ + chain: arbitrum, + transport: http(), + account, + }) + + // Set up public client for reading transaction receipts + const publicClient = createPublicClient({ + chain: arbitrum, + transport: http(), + }) + + const walletAddress = account.address + consola.info(`Connected wallet: ${walletAddress}`) + + // Amount to bridge: 0.001 WETH + const bridgeAmount = parseUnits('0.001', 18) + consola.info(`Bridge amount: 0.001 WETH`) + + // Check WETH balance + const wethContract = getContract({ + address: ARBITRUM_WETH as Hex, + abi: ERC20_ABI, + client: { public: walletClient, wallet: walletClient }, + }) + + const wethBalance = (await wethContract.read.balanceOf([ + walletAddress, + ])) as bigint + consola.info(`WETH balance: ${wethBalance}`) + + if (wethBalance < bridgeAmount && !options.dryRun) { + consola.error(`Insufficient WETH balance. Need at least 0.001 WETH.`) + process.exit(1) + } else if (options.dryRun && wethBalance < bridgeAmount) { + consola.warn( + `[DRY RUN] Insufficient WETH balance, but continuing for demo purposes` + ) + } + + // Check allowance for LiFi Diamond + const allowance = (await wethContract.read.allowance([ + walletAddress, + LIFI_DIAMOND_ARBITRUM, + ])) as bigint + consola.info(`Current allowance: ${allowance}`) + + if (allowance < bridgeAmount) { + consola.info('Approving WETH for LiFi Diamond...') + if (!options.dryRun) { + try { + const approveTx = await wethContract.write.approve([ + LIFI_DIAMOND_ARBITRUM as `0x${string}`, + BigInt( + '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + ), // Max uint256 + ]) + consola.success(`Approval transaction sent: ${approveTx}`) + + // Wait for approval confirmation + consola.info('Waiting for approval confirmation...') + const approvalReceipt = await publicClient.waitForTransactionReceipt({ + hash: approveTx, + timeout: 60_000, // 60 seconds timeout + }) + + if (approvalReceipt.status === 'success') { + consola.success(`✅ Approval confirmed!`) + } else { + consola.error(`❌ Approval failed!`) + process.exit(1) + } + } catch (error) { + consola.error('Approval transaction failed:', error) + process.exit(1) + } + } else { + consola.info(`[DRY RUN] Would approve WETH for LiFi Diamond`) + } + } + + // Fetch cross-chain route with destination swap + consola.info('Fetching cross-chain route with destination swap...') + const route = await fetchCrossChainRoute( + bridgeAmount.toString(), + walletAddress + ) + + // Extract route details for our calldata construction + const routeDetails = extractRouteDetails(route) + + // Generate a transaction ID for the bridge + const transactionId = `0x${randomBytes(32).toString('hex')}` + + // Calculate the actual amount that will be received after relayer fee + const actualReceivedAmount = + (BigInt(routeDetails.toAmount) * BigInt('980000000000000000')) / + BigInt('1000000000000000000') + + // Encode the destination call message for ReceiverAcrossV3 using Patcher pattern + const destinationCallMessage = encodeDestinationCallMessage( + transactionId, + actualReceivedAmount.toString(), // Use actual received amount instead of original bridge amount + routeDetails.swapToAmountMin, + walletAddress + ) + + // Construct our own bridge calldata using LiFi's route data + const bridgeCallData = constructBridgeCallData( + routeDetails, + destinationCallMessage, + walletAddress + ) + + // Log the route details + consola.success('Cross-chain route with destination swap ready!') + consola.info('✅ Bridge: AcrossV3 (WETH Arbitrum → Base)') + consola.info( + '✅ Destination swap: WETH → USDC on Base via Patcher + LiFiDEXAggregator' + ) + consola.info('✅ Final output: USDC to user wallet') + consola.info( + '✅ Calldata: Constructed using Patcher pattern with dynamic balance patching' + ) + + // Log cost breakdown using LiFi's data + consola.info('💰 Cost breakdown (from LiFi route):') + consola.info(`- Bridge amount: ${bridgeAmount} wei (0.001 WETH)`) + consola.info(`- Expected bridge output: ${routeDetails.toAmount} wei WETH`) + consola.info(`- Expected swap output: ${routeDetails.finalAmount} USDC`) + consola.info( + `- Minimum swap output: ${routeDetails.finalAmountMin} USDC (with slippage)` + ) + consola.info(`- Estimated gas cost: $${routeDetails.gasCostUSD}`) + + consola.info('🔄 Cross-chain flow with Patcher deposit pattern:') + consola.info('1. Bridge 0.001 WETH from Arbitrum → Base via AcrossV3') + consola.info( + `2. ReceiverAcrossV3.handleV3AcrossMessage receives ~${routeDetails.toAmount} wei WETH on Base` + ) + consola.info( + '3. ReceiverAcrossV3 calls Executor.swapAndCompleteBridgeTokens with 2 patcher calls:' + ) + consola.info( + ' a. Patcher deposits WETH from Executor and approves LiFiDexAggregator with balance patching' + ) + consola.info( + ' b. Patcher calls LiFiDexAggregator::processRoute(patcherBalance) - Swap exact amount' + ) + consola.info( + '4. All calls use dynamic balance patching to handle exact bridge amounts' + ) + consola.info('5. Final USDC sent to user wallet') + + // Execute the cross-chain transaction + if (!options.dryRun) { + consola.info('Executing cross-chain bridge with destination swap...') + + try { + const txHash = await walletClient.sendTransaction({ + to: LIFI_DIAMOND_ARBITRUM as `0x${string}`, + data: bridgeCallData as `0x${string}`, + value: 0n, // No ETH value needed for WETH bridge + gas: 800000n, // Increased gas limit for complex operations + }) + + consola.success(`✅ Transaction sent: ${txHash}`) + consola.info('Waiting for transaction confirmation...') + + const receipt = await publicClient.waitForTransactionReceipt({ + hash: txHash, + timeout: 300_000, // 5 minutes timeout + }) + + if (receipt.status === 'success') { + consola.success( + `🎉 Cross-chain bridge with destination swap completed using Patcher deposit pattern!` + ) + consola.info(`Transaction hash: ${txHash}`) + consola.info(`Block number: ${receipt.blockNumber}`) + consola.info(`Gas used: ${receipt.gasUsed}`) + consola.info('🔍 Check your Base wallet for USDC!') + } else { + consola.error(`❌ Transaction failed!`) + consola.info(`Transaction hash: ${txHash}`) + } + } catch (error) { + consola.error('Transaction execution failed:', error) + process.exit(1) + } + } else { + consola.info( + '[DRY RUN] Would execute cross-chain bridge with destination swap using Patcher deposit pattern' + ) + consola.info(`[DRY RUN] Transaction data:`) + consola.info(`[DRY RUN] - To: ${LIFI_DIAMOND_ARBITRUM}`) + consola.info(`[DRY RUN] - Value: 0`) + consola.info(`[DRY RUN] - Gas limit: 500000`) + consola.info(`[DRY RUN] - Data length: ${bridgeCallData.length} characters`) + } +} + +// CLI command definition +const main = defineCommand({ + meta: { + name: 'demoPatcherDest', + description: + 'Demo cross-chain bridge with destination swap using AcrossV3, Patcher pattern, and LiFi Advanced Routes API', + }, + args: { + privateKey: { + type: 'string', + description: 'Private key for the wallet', + required: true, + }, + dryRun: { + type: 'boolean', + description: 'Perform a dry run without executing transactions', + default: false, + }, + }, + async run({ args }) { + if (!args.privateKey) { + consola.error('Private key is required') + process.exit(1) + } + + try { + await executeCrossChainBridgeWithSwap({ + privateKey: args.privateKey, + dryRun: args.dryRun, + }) + } catch (error) { + consola.error('Demo failed:', error) + process.exit(1) + } + }, +}) + +// Run the CLI +runMain(main) diff --git a/script/demoScripts/utils/cowSwapHelpers.ts b/script/demoScripts/utils/cowSwapHelpers.ts new file mode 100644 index 000000000..8a1f9d7d5 --- /dev/null +++ b/script/demoScripts/utils/cowSwapHelpers.ts @@ -0,0 +1,429 @@ +import { + parseAbi, + encodeFunctionData, + recoverMessageAddress, + keccak256, + encodePacked, + pad, + getAddress, +} from 'viem' +import { randomBytes } from 'crypto' +import { ethers } from 'ethers' +import { COW_SHED_FACTORY, COW_SHED_IMPLEMENTATION } from '@cowprotocol/cow-sdk' +import { consola } from 'consola' +import { + generateNeedle, + findNeedleOffset, + generateExecuteWithDynamicPatchesCalldata, + generateBalanceOfCalldata, +} from './patcherHelpers' + +// EIP-1967 transparent proxy creation bytecode for CowShed user proxies +// This bytecode creates a minimal proxy that delegates calls to the CowShed implementation +// while storing the implementation address in the standard EIP-1967 storage slot +const PROXY_CREATION_CODE = + '0x60a034608e57601f61037138819003918201601f19168301916001600160401b038311848410176093578084926040948552833981010312608e57604b602060458360a9565b920160a9565b6080527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc556040516102b490816100bd8239608051818181608f01526101720152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203608e5756fe60806040526004361015610018575b3661019457610194565b6000803560e01c908163025b22bc1461003b575063f851a4400361000e5761010d565b3461010a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261010a5773ffffffffffffffffffffffffffffffffffffffff60043581811691828203610106577f0000000000000000000000000000000000000000000000000000000000000000163314600014610101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8280a280f35b61023d565b8380fd5b80fd5b346101645760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610164576020610146610169565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b600080fd5b333003610101577f000000000000000000000000000000000000000000000000000000000000000090565b60ff7f68df44b1011761f481358c0f49a711192727fb02c377d697bcb0ea8ff8393ac0541615806101ef575b1561023d5760046040517ff92ee8a9000000000000000000000000000000000000000000000000000000008152fd5b507f400ada75000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000006000351614156101c0565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546000808092368280378136915af43d82803e1561027a573d90f35b3d90fdfea2646970667358221220c7c26ff3040b96a28e96d6d27b743972943aeaef81cc821544c5fe1e24f9b17264736f6c63430008190033' + +/** + * Compute the deterministic proxy address for a CowShed user + */ +export function computeCowShedProxyAddress( + factoryAddress: string, + implementationAddress: string, + owner: string +): `0x${string}` { + const salt = ethers.utils.defaultAbiCoder.encode(['address'], [owner]) + const initCodeHash = ethers.utils.solidityKeccak256( + ['bytes', 'bytes'], + [ + PROXY_CREATION_CODE, + ethers.utils.defaultAbiCoder.encode( + ['address', 'address'], + [implementationAddress, owner] + ), + ] + ) + return ethers.utils.getCreate2Address( + factoryAddress, + salt, + initCodeHash + ) as `0x${string}` +} + +/** + * Encode the executeHooks call for the CowShed factory + */ +export function encodeCowShedExecuteHooks( + calls: any[], + nonce: `0x${string}`, + deadline: bigint, + owner: `0x${string}`, + signature: `0x${string}` +): string { + const cowShedFactoryAbi = parseAbi([ + 'function executeHooks((address target, uint256 value, bytes callData, bool allowFailure, bool isDelegateCall)[] calls, bytes32 nonce, uint256 deadline, address user, bytes signature) returns (address proxy)', + ]) + + return encodeFunctionData({ + abi: cowShedFactoryAbi, + functionName: 'executeHooks', + args: [ + calls.map((call) => ({ + target: getAddress(call.target), + value: call.value, + callData: call.callData, + allowFailure: call.allowFailure, + isDelegateCall: call.isDelegateCall, + })), + nonce, + deadline, + owner, + signature, + ], + }) +} + +export interface CowShedPostHooksConfig { + chainId: number + walletClient: any + usdcAddress: string + receivedAmount: bigint + lifiDiamondAddress: string + patcherAddress: string + baseUsdcAddress: string + destinationChainId: bigint +} + +/** + * Setup CowShed post hooks for bridging USDC to BASE using Relay + */ +export async function setupCowShedPostHooks(config: CowShedPostHooksConfig) { + const { + chainId, + walletClient, + usdcAddress, + receivedAmount, + lifiDiamondAddress, + patcherAddress, + baseUsdcAddress, + destinationChainId, + } = config + + const account = walletClient.account + const signerAddress = account.address + + // Generate a random nonce + const nonce = `0x${Array.from({ length: 64 }, () => + Math.floor(Math.random() * 16).toString(16) + ).join('')}` as `0x${string}` + + // Set a deadline 24 hours from now + const deadline = BigInt(Math.floor(Date.now() / 1000) + 24 * 60 * 60) + + // Get the proxy address + const shedDeterministicAddress = computeCowShedProxyAddress( + COW_SHED_FACTORY, + COW_SHED_IMPLEMENTATION, + signerAddress + ) + consola.info(`CowShed proxy address: ${shedDeterministicAddress}`) + + // Create the bridge data for LiFi + const bridgeData = { + transactionId: `0x${randomBytes(32).toString('hex')}` as `0x${string}`, + bridge: 'relay', + integrator: 'TestIntegrator', + referrer: '0x0000000000000000000000000000000000000000' as `0x${string}`, + sendingAssetId: usdcAddress as `0x${string}`, + receiver: signerAddress as `0x${string}`, + minAmount: receivedAmount, + destinationChainId, + hasSourceSwaps: false, + hasDestinationCall: false, + } + + // Create RelayData + // First, create a quote request with a realistic amount + const estimatedUsdcAmount = '1000000' // 1 USDC (6 decimals) + + // Get a real signature from the Relay API + // First, create a quote request + // Use LiFi Diamond as the user since it will be the final caller of RelayFacet + const quoteParams = { + user: lifiDiamondAddress, // LiFi Diamond will be address(this) in RelayFacet + originChainId: chainId, + destinationChainId: Number(destinationChainId), + originCurrency: usdcAddress, + destinationCurrency: baseUsdcAddress, + recipient: signerAddress, + tradeType: 'EXACT_INPUT', + amount: estimatedUsdcAmount, // Use a realistic amount instead of 0 + referrer: 'lifi-demo', + useExternalLiquidity: false, + } + + // Fetch the quote from the Relay API + consola.info('Fetching quote from Relay API...') + const quoteResponse = await fetch('https://api.relay.link/quote', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(quoteParams), + }) + + if (!quoteResponse.ok) { + throw new Error( + `Failed to get quote from Relay API: ${quoteResponse.statusText}` + ) + } + + const quoteData = await quoteResponse.json() + const relayRequestId = quoteData.steps[0].requestId + consola.info(`Got requestId from Relay API: ${relayRequestId}`) + + // Fetch the signature from the Relay API + consola.info('Fetching signature from Relay API...') + const signatureResponse = await fetch( + `https://api.relay.link/requests/${relayRequestId}/signature/v2`, + { headers: { 'Content-Type': 'application/json' } } + ) + + if (!signatureResponse.ok) { + throw new Error( + `Failed to get signature from Relay API: ${signatureResponse.statusText}` + ) + } + + const signatureData = await signatureResponse.json() + const relaySignature = signatureData.signature as `0x${string}` + consola.info( + `Got signature from Relay API: ${relaySignature.slice( + 0, + 10 + )}...${relaySignature.slice(-8)}` + ) + + // Log the request origin user (not the signer) + if (signatureData.requestData?.originUser) { + const originUser = signatureData.requestData.originUser + consola.info(`Request origin user: ${originUser} (LiFi Diamond)`) + } + + // Optional signature verification for debugging purposes + // This code verifies that the signature from Relay API is valid by recovering the signer + // It's not required for functionality but helps ensure the signature is working correctly + // Recover the actual signer using the same message format as the contract + try { + // Construct the message exactly as the contract does: + // Use viem's encodePacked instead of manual concatenation + const packedData = encodePacked( + [ + 'bytes32', + 'uint256', + 'bytes32', + 'bytes32', + 'uint256', + 'bytes32', + 'bytes32', + ], + [ + relayRequestId as `0x${string}`, // requestId + BigInt(chainId), // chainId + pad(lifiDiamondAddress as `0x${string}`), // LiFi Diamond address as bytes32 (address(this) in RelayFacet) + pad(usdcAddress as `0x${string}`), // sendingAssetId as bytes32 + destinationChainId, // destinationChainId + pad(signerAddress as `0x${string}`), // receiver as bytes32 + pad(baseUsdcAddress as `0x${string}`), // receivingAssetId as bytes32 + ] + ) + + // Hash the packed data + const messageHash = keccak256(packedData) + + // Recover the signer using the message hash (Ethereum signed message format) + const recoveredSigner = await recoverMessageAddress({ + message: { raw: messageHash }, + signature: relaySignature, + }) + + consola.success(`Relay attestation signer: ${recoveredSigner}`) + } catch (error) { + consola.warn('Could not recover signer address:', error) + // Fallback: log full response for debugging + consola.debug( + 'Full signature response:', + JSON.stringify(signatureData, null, 2) + ) + } + + const relayData = { + requestId: relayRequestId, + nonEVMReceiver: + '0x0000000000000000000000000000000000000000000000000000000000000000' as `0x${string}`, // Not bridging to non-EVM chain + receivingAssetId: pad(baseUsdcAddress as `0x${string}`), // Use viem's pad instead of manual padStart + signature: relaySignature, // Real signature from the Relay API + } + + // Encode the RelayFacet call + const relayFacetAbi = parseAbi([ + 'function startBridgeTokensViaRelay((bytes32 transactionId, string bridge, string integrator, address referrer, address sendingAssetId, address receiver, uint256 minAmount, uint256 destinationChainId, bool hasSourceSwaps, bool hasDestinationCall) _bridgeData, (bytes32 requestId, bytes32 nonEVMReceiver, bytes32 receivingAssetId, bytes signature) _relayData) payable', + ]) + + // Create the bridge data with proper types + const typedBridgeData = { + transactionId: bridgeData.transactionId, + bridge: bridgeData.bridge, + integrator: bridgeData.integrator, + referrer: bridgeData.referrer, + sendingAssetId: bridgeData.sendingAssetId, + receiver: bridgeData.receiver, + destinationChainId: bridgeData.destinationChainId, + minAmount: bridgeData.minAmount, + hasSourceSwaps: bridgeData.hasSourceSwaps, + hasDestinationCall: bridgeData.hasDestinationCall, + } + + // Create the relay data with proper types + const typedRelayData = { + requestId: relayData.requestId, + nonEVMReceiver: relayData.nonEVMReceiver, + receivingAssetId: relayData.receivingAssetId, + signature: relayData.signature, + } + + // Generate a random bytes32 hex value as needle to find the minAmount position + const minAmountNeedle = generateNeedle() + + // Create calldata with the needle in place of minAmount (will be patched by Patcher) + const bridgeDataWithNeedle = { + ...typedBridgeData, + minAmount: minAmountNeedle, // Pass as hex string directly + } + + const relayCalldata = encodeFunctionData({ + abi: relayFacetAbi, + functionName: 'startBridgeTokensViaRelay', + args: [bridgeDataWithNeedle as any, typedRelayData], + }) + + // Find the needle position in the calldata + const minAmountOffset = findNeedleOffset(relayCalldata, minAmountNeedle) + consola.info( + `Found minAmount offset using dynamic search: ${minAmountOffset} bytes` + ) + + // Note: This offset is specifically for startBridgeTokensViaRelay function + // Different bridge functions may have different offsets due to different parameter layouts + + // Encode the balanceOf call to get the USDC balance + const valueGetter = generateBalanceOfCalldata(shedDeterministicAddress) + + // Encode the patcher call + const patcherCalldata = generateExecuteWithDynamicPatchesCalldata( + usdcAddress as `0x${string}`, // valueSource - USDC contract + valueGetter, // valueGetter - balanceOf call + lifiDiamondAddress as `0x${string}`, // finalTarget - LiFiDiamond contract + relayCalldata as `0x${string}`, // data - the encoded RelayFacet call + [minAmountOffset], // offsets - Array with position of minAmount in the calldata + 0n, // value - no ETH being sent + false // delegateCall + ) + + // Encode the USDC approval call for the DIAMOND address + const approvalCalldata = encodeFunctionData({ + abi: parseAbi([ + 'function approve(address spender, uint256 amount) returns (bool)', + ]), + functionName: 'approve', + args: [ + lifiDiamondAddress as `0x${string}`, // spender - LiFi Diamond + BigInt( + '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + ), // Max uint256 approval + ], + }) + + // Define the post-swap calls: first approval, then bridge + const postSwapCalls = [ + { + target: usdcAddress as `0x${string}`, + callData: approvalCalldata, + value: 0n, + allowFailure: false, + isDelegateCall: false, + }, + { + target: patcherAddress as `0x${string}`, + callData: patcherCalldata, + value: 0n, + allowFailure: false, + isDelegateCall: true, + }, + ] + + // Create the typed data for the hooks + const typedData = { + account, + domain: { + name: 'COWShed', + version: '1.0.0', + chainId: BigInt(chainId), + verifyingContract: shedDeterministicAddress, + }, + types: { + ExecuteHooks: [ + { name: 'calls', type: 'Call[]' }, + { name: 'nonce', type: 'bytes32' }, + { name: 'deadline', type: 'uint256' }, + ], + Call: [ + { name: 'target', type: 'address' }, + { name: 'value', type: 'uint256' }, + { name: 'callData', type: 'bytes' }, + { name: 'allowFailure', type: 'bool' }, + { name: 'isDelegateCall', type: 'bool' }, + ], + }, + primaryType: 'ExecuteHooks', + message: { + calls: postSwapCalls.map((call) => ({ + target: call.target, + value: call.value, + callData: call.callData, + allowFailure: call.allowFailure, + isDelegateCall: call.isDelegateCall, + })), + nonce, + deadline, + }, + } + + // Sign the typed data for the hooks + const hookSignature = (await walletClient.signTypedData( + typedData + )) as `0x${string}` + + // Encode the post hooks call data + const shedEncodedPostHooksCallData = encodeCowShedExecuteHooks( + postSwapCalls, + nonce, + deadline, + signerAddress as `0x${string}`, + hookSignature + ) + + // Create the post hooks + const postHooks = [ + { + target: COW_SHED_FACTORY, + callData: shedEncodedPostHooksCallData, + gasLimit: '3000000', + }, + ] + + return { + shedDeterministicAddress, + postHooks, + } +} diff --git a/script/demoScripts/utils/patcherHelpers.ts b/script/demoScripts/utils/patcherHelpers.ts new file mode 100644 index 000000000..4f60022ae --- /dev/null +++ b/script/demoScripts/utils/patcherHelpers.ts @@ -0,0 +1,142 @@ +import { randomBytes } from 'crypto' +import { encodeFunctionData, parseAbi, type Hex } from 'viem' + +/** + * Normalize calldata string by removing '0x' prefix if present + * @param calldata - The calldata string to normalize + * @returns Normalized calldata string without '0x' prefix + */ +export const normalizeCalldata = (calldata: string): string => { + return calldata.startsWith('0x') ? calldata.slice(2) : calldata +} + +/** + * Find hex value positions + * @param haystack The larger hex string (calldata) to search within + * @param needle The hex pattern/value to search for within the haystack + * @returns Array of byte offsets where the needle pattern is found in the haystack + */ +export const findHexValueOccurrences = ( + haystack: string, + needle: string +): readonly number[] => { + // Normalize both haystack and needle + const cleanHaystack = normalizeCalldata(haystack) + const cleanNeedle = normalizeCalldata(needle) + + const findRec = ( + startPos: number, + acc: readonly number[] + ): readonly number[] => { + const foundPos = cleanHaystack.indexOf(cleanNeedle, startPos) + + if (foundPos === -1) { + return acc + } + + const byteOffset = foundPos / 2 + return findRec(foundPos + cleanNeedle.length, [...acc, byteOffset]) + } + return findRec(0, []) +} + +/** + * Generate a random 32-byte hex needle for offset discovery + */ +export function generateNeedle(): Hex { + return `0x${randomBytes(32).toString('hex')}` as Hex +} + +/** + * Find offset of a needle in calldata + */ +export function findNeedleOffset(calldata: string, needle: Hex): bigint { + const positions = findHexValueOccurrences(calldata, needle) + + if (positions.length === 0) { + throw new Error(`Could not find needle ${needle} in calldata`) + } + + if (positions.length > 1) { + throw new Error( + `Found multiple occurrences of needle ${needle} in calldata` + ) + } + + return BigInt(positions[0]) +} + +/** + * Generate calldata for executeWithDynamicPatches + */ +export function generateExecuteWithDynamicPatchesCalldata( + valueSource: Hex, + valueGetter: Hex, + finalTarget: Hex, + targetCalldata: Hex, + offsets: bigint[], + value = 0n, + delegateCall = false +): Hex { + const patcherAbi = parseAbi([ + 'function executeWithDynamicPatches(address valueSource, bytes valueGetter, address finalTarget, uint256 value, bytes data, uint256[] offsets, bool delegateCall) returns (bool success, bytes returnData)', + ]) + + return encodeFunctionData({ + abi: patcherAbi, + functionName: 'executeWithDynamicPatches', + args: [ + valueSource, + valueGetter, + finalTarget, + value, + targetCalldata, + offsets, + delegateCall, + ], + }) as Hex +} + +/** + * Generate calldata for executeWithMultiplePatches + */ +export function generateExecuteWithMultiplePatchesCalldata( + valueSources: Hex[], + valueGetters: Hex[], + finalTarget: Hex, + targetCalldata: Hex, + offsetGroups: bigint[][], + value = 0n, + delegateCall = false +): Hex { + const patcherAbi = parseAbi([ + 'function executeWithMultiplePatches(address[] valueSources, bytes[] valueGetters, address finalTarget, uint256 value, bytes data, uint256[][] offsetGroups, bool delegateCall) returns (bool success, bytes returnData)', + ]) + + return encodeFunctionData({ + abi: patcherAbi, + functionName: 'executeWithMultiplePatches', + args: [ + valueSources, + valueGetters, + finalTarget, + value, + targetCalldata, + offsetGroups, + delegateCall, + ], + }) as Hex +} + +/** + * Generate balanceOf calldata for use as valueGetter + */ +export function generateBalanceOfCalldata(account: Hex): Hex { + return encodeFunctionData({ + abi: parseAbi([ + 'function balanceOf(address account) view returns (uint256)', + ]), + functionName: 'balanceOf', + args: [account], + }) as Hex +} diff --git a/script/deploy/facets/DeployPatcher.s.sol b/script/deploy/facets/DeployPatcher.s.sol new file mode 100644 index 000000000..24e53a4a4 --- /dev/null +++ b/script/deploy/facets/DeployPatcher.s.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.17; + +import { DeployScriptBase } from "./utils/DeployScriptBase.sol"; +import { Patcher } from "lifi/Periphery/Patcher.sol"; + +contract DeployScript is DeployScriptBase { + constructor() DeployScriptBase("Patcher") {} + + function run() public returns (Patcher deployed) { + deployed = Patcher(deploy(type(Patcher).creationCode)); + } +} diff --git a/src/Periphery/Patcher.sol b/src/Periphery/Patcher.sol new file mode 100644 index 000000000..436cceb6c --- /dev/null +++ b/src/Periphery/Patcher.sol @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import { LibAsset, IERC20 } from "../Libraries/LibAsset.sol"; + +/// @title Patcher +/// @author LI.FI (https://li.fi) +/// @notice A contract that patches calldata with dynamically retrieved values before execution +/// @dev Designed to be used with both delegate calls and normal calls +/// @custom:version 1.0.0 +contract Patcher { + /// @notice Error when getting a dynamic value fails + error FailedToGetDynamicValue(); + + /// @notice Error when input arrays have mismatched lengths + error MismatchedArrayLengths(); + + /// @notice Error when a patch offset is invalid + error InvalidPatchOffset(); + + /// @notice Error when a call execution fails + error CallExecutionFailed(); + + /// External Methods /// + + /// @notice Retrieves a value dynamically and uses it to patch calldata before execution + /// @param valueSource The contract to query for the dynamic value + /// @param valueGetter The calldata to use to get the dynamic value (e.g., balanceOf call) + /// @param finalTarget The contract to call with the patched data + /// @param value The ETH value to send with the final call + /// @param data The original calldata to patch and execute + /// @param offsets Array of byte offsets in the original calldata to patch with the dynamic value + /// @param delegateCall If true, executes a delegatecall instead of a regular call for the final call + /// @return success Whether the final call was successful + /// @return returnData The data returned by the final call + function executeWithDynamicPatches( + address valueSource, + bytes calldata valueGetter, + address finalTarget, + uint256 value, + bytes calldata data, + uint256[] calldata offsets, + bool delegateCall + ) external payable returns (bool success, bytes memory returnData) { + return + _executeWithDynamicPatches( + valueSource, + valueGetter, + finalTarget, + value, + data, + offsets, + delegateCall + ); + } + + /// @notice Deposits tokens and retrieves a value dynamically to patch calldata before execution + /// @param tokenAddress The ERC20 token to transfer from msg.sender + /// @param valueSource The contract to query for the dynamic value + /// @param valueGetter The calldata to use to get the dynamic value (e.g., balanceOf call) + /// @param finalTarget The contract to call with the patched data + /// @param value The ETH value to send with the final call + /// @param data The original calldata to patch and execute + /// @param offsets Array of byte offsets in the original calldata to patch with the dynamic value + /// @param delegateCall If true, executes a delegatecall instead of a regular call for the final call + /// @return success Whether the final call was successful + /// @return returnData The data returned by the final call + function depositAndExecuteWithDynamicPatches( + address tokenAddress, + address valueSource, + bytes calldata valueGetter, + address finalTarget, + uint256 value, + bytes calldata data, + uint256[] calldata offsets, + bool delegateCall + ) external payable returns (bool success, bytes memory returnData) { + // Get the token balance of msg.sender + uint256 amount = IERC20(tokenAddress).balanceOf(msg.sender); + + // Transfer tokens from msg.sender to this contract + LibAsset.transferFromERC20( + tokenAddress, + msg.sender, + address(this), + amount + ); + + // Approve the finalTarget to spend the deposited tokens + LibAsset.maxApproveERC20(IERC20(tokenAddress), finalTarget, amount); + + return + _executeWithDynamicPatches( + valueSource, + valueGetter, + finalTarget, + value, + data, + offsets, + delegateCall + ); + } + + /// @notice Deposits tokens and retrieves multiple values dynamically to patch calldata at different offsets + /// @param tokenAddress The ERC20 token to transfer from msg.sender + /// @param valueSources Array of contracts to query for dynamic values + /// @param valueGetters Array of calldata to use to get each dynamic value + /// @param finalTarget The contract to call with the patched data + /// @param value The ETH value to send with the final call + /// @param data The original calldata to patch and execute + /// @param offsetGroups Array of offset arrays, each corresponding to a value source/getter pair + /// @param delegateCall If true, executes a delegatecall instead of a regular call for the final call + /// @return success Whether the final call was successful + /// @return returnData The data returned by the final call + function depositAndExecuteWithMultiplePatches( + address tokenAddress, + address[] calldata valueSources, + bytes[] calldata valueGetters, + address finalTarget, + uint256 value, + bytes calldata data, + uint256[][] calldata offsetGroups, + bool delegateCall + ) external payable returns (bool success, bytes memory returnData) { + // Get the token balance of msg.sender + uint256 amount = IERC20(tokenAddress).balanceOf(msg.sender); + + // Transfer tokens from msg.sender to this contract + LibAsset.transferFromERC20( + tokenAddress, + msg.sender, + address(this), + amount + ); + + // Approve the finalTarget to spend the deposited tokens + LibAsset.maxApproveERC20(IERC20(tokenAddress), finalTarget, amount); + + return + _executeWithMultiplePatches( + valueSources, + valueGetters, + finalTarget, + value, + data, + offsetGroups, + delegateCall + ); + } + + /// @notice Retrieves multiple values dynamically and uses them to patch calldata at different offsets + /// @param valueSources Array of contracts to query for dynamic values + /// @param valueGetters Array of calldata to use to get each dynamic value + /// @param finalTarget The contract to call with the patched data + /// @param value The ETH value to send with the final call + /// @param data The original calldata to patch and execute + /// @param offsetGroups Array of offset arrays, each corresponding to a value source/getter pair + /// @param delegateCall If true, executes a delegatecall instead of a regular call for the final call + /// @return success Whether the final call was successful + /// @return returnData The data returned by the final call + function executeWithMultiplePatches( + address[] calldata valueSources, + bytes[] calldata valueGetters, + address finalTarget, + uint256 value, + bytes calldata data, + uint256[][] calldata offsetGroups, + bool delegateCall + ) external payable returns (bool success, bytes memory returnData) { + return + _executeWithMultiplePatches( + valueSources, + valueGetters, + finalTarget, + value, + data, + offsetGroups, + delegateCall + ); + } + + /// Private Methods /// + + /// @notice Helper function to get a dynamic value from an external contract + /// @param valueSource The contract to query for the dynamic value + /// @param valueGetter The calldata to use to get the dynamic value + /// @return dynamicValue The uint256 value retrieved from the call + function _getDynamicValue( + address valueSource, + bytes calldata valueGetter + ) internal view returns (uint256 dynamicValue) { + (bool valueSuccess, bytes memory valueData) = valueSource.staticcall( + valueGetter + ); + if (!valueSuccess) revert FailedToGetDynamicValue(); + + dynamicValue = abi.decode(valueData, (uint256)); + } + + /// @notice Helper function to apply a patch at a specific offset + /// @param patchedData The data to patch + /// @param offset The byte offset in the data + /// @param dynamicValue The value to write at the offset + function _applyPatch( + bytes memory patchedData, + uint256 offset, + uint256 dynamicValue + ) internal pure { + if (offset + 32 > patchedData.length) revert InvalidPatchOffset(); + + assembly { + // Calculate the position in memory where we need to write the new value + let position := add(add(patchedData, 32), offset) + + // Store the new value at the calculated position + mstore(position, dynamicValue) + } + } + + /// @notice Helper function to execute the final call + /// @param finalTarget The contract to call + /// @param value The ETH value to send + /// @param patchedData The patched calldata to use + /// @param delegateCall Whether to use delegatecall + /// @return success Whether the call was successful + /// @return returnData The data returned by the call + function _executeCall( + address finalTarget, + uint256 value, + bytes memory patchedData, + bool delegateCall + ) internal returns (bool success, bytes memory returnData) { + if (delegateCall) { + (success, returnData) = finalTarget.delegatecall(patchedData); + } else { + (success, returnData) = finalTarget.call{ value: value }( + patchedData + ); + } + + if (!success) { + // Revert with the returned error data if available + if (returnData.length > 0) { + assembly { + revert(add(returnData, 32), mload(returnData)) + } + } else { + revert CallExecutionFailed(); + } + } + } + + /// @dev Internal implementation to avoid stack too deep errors + function _executeWithDynamicPatches( + address valueSource, + bytes calldata valueGetter, + address finalTarget, + uint256 value, + bytes calldata data, + uint256[] calldata offsets, + bool delegateCall + ) internal returns (bool success, bytes memory returnData) { + // Get the dynamic value + uint256 dynamicValue = _getDynamicValue(valueSource, valueGetter); + + bytes memory patchedData = _createPatchedData( + data, + offsets, + dynamicValue + ); + + // Execute the call with the patched data + return _executeCall(finalTarget, value, patchedData, delegateCall); + } + + /// @dev Internal implementation to avoid stack too deep errors + function _executeWithMultiplePatches( + address[] calldata valueSources, + bytes[] calldata valueGetters, + address finalTarget, + uint256 value, + bytes calldata data, + uint256[][] calldata offsetGroups, + bool delegateCall + ) internal returns (bool success, bytes memory returnData) { + // Validation + if ( + valueSources.length != valueGetters.length || + valueSources.length != offsetGroups.length + ) { + revert MismatchedArrayLengths(); + } + + // Create a mutable copy of the original calldata + bytes memory patchedData = bytes(data); + + // Process patches in batches to avoid stack too deep + _processPatches(valueSources, valueGetters, offsetGroups, patchedData); + + // Execute the call with the patched data + return _executeCall(finalTarget, value, patchedData, delegateCall); + } + + /// @dev Helper function to process patches in batches + function _processPatches( + address[] calldata valueSources, + bytes[] calldata valueGetters, + uint256[][] calldata offsetGroups, + bytes memory patchedData + ) internal view { + for (uint256 i = 0; i < valueSources.length; ) { + // Get the dynamic value for this patch + uint256 dynamicValue = _getDynamicValue( + valueSources[i], + valueGetters[i] + ); + + // Apply the patches for this value + uint256[] calldata offsets = offsetGroups[i]; + _applyPatches(patchedData, offsets, dynamicValue); + + unchecked { + ++i; + } + } + } + + /// @notice Helper function to apply multiple patches with the same value + /// @param patchedData The data to patch + /// @param offsets Array of offsets where to apply the patches + /// @param dynamicValue The value to write at each offset + function _applyPatches( + bytes memory patchedData, + uint256[] calldata offsets, + uint256 dynamicValue + ) internal pure { + for (uint256 j = 0; j < offsets.length; ) { + _applyPatch(patchedData, offsets[j], dynamicValue); + + unchecked { + ++j; + } + } + } + + /// @notice Creates a patched copy of input data with a dynamic value applied at specified offsets + /// @dev Uses assembly for efficient memory operations without expensive memory copies + /// @param data The original calldata to patch + /// @param offsets Array of byte offsets where the dynamic value should be written + /// @param dynamicValue The value to write at each offset + /// @return patchedData The new bytes array containing the patched data + function _createPatchedData( + bytes calldata data, + uint256[] calldata offsets, + uint256 dynamicValue + ) internal pure returns (bytes memory patchedData) { + uint256 dataLength = data.length; + + assembly { + // allocate memory for result + patchedData := mload(0x40) + mstore(patchedData, dataLength) + + // calculate and set new free memory pointer + let patchedDataEnd := add(add(patchedData, 0x20), dataLength) + mstore(0x40, patchedDataEnd) + + // copy calldata directly to memory + calldatacopy(add(patchedData, 0x20), data.offset, dataLength) + } + + // single simple loop for 1-2 offsets + for (uint256 i = 0; i < offsets.length; i++) { + if (offsets[i] + 32 > dataLength) { + revert InvalidPatchOffset(); + } + + _applyPatch(patchedData, offsets[i], dynamicValue); + } + } +} diff --git a/test/solidity/Periphery/Patcher.t.sol b/test/solidity/Periphery/Patcher.t.sol new file mode 100644 index 000000000..484684405 --- /dev/null +++ b/test/solidity/Periphery/Patcher.t.sol @@ -0,0 +1,1256 @@ +// SPDX-License-Identifier: Unlicensed +pragma solidity ^0.8.17; + +import { TestBase } from "../utils/TestBase.sol"; +import { Patcher } from "../../../src/Periphery/Patcher.sol"; +import { TestToken as ERC20 } from "../utils/TestToken.sol"; +import { ILiFi } from "../../../src/Interfaces/ILiFi.sol"; +import { RelayFacet } from "../../../src/Facets/RelayFacet.sol"; +import { LibAsset } from "../../../src/Libraries/LibAsset.sol"; +import { LibAllowList } from "../../../src/Libraries/LibAllowList.sol"; + +error MockFailure(); +error TargetFailure(); +error OracleFailure(); +error PriceNotSet(); + +contract MockValueSource { + uint256 public value; + bool public shouldFail; + + function setValue(uint256 _value) external { + value = _value; + } + + function setShouldFail(bool _shouldFail) external { + shouldFail = _shouldFail; + } + + function getValue() external view returns (uint256) { + if (shouldFail) { + revert MockFailure(); + } + return value; + } + + function getBalance( + address token, + address account + ) external view returns (uint256) { + if (shouldFail) { + revert MockFailure(); + } + return ERC20(token).balanceOf(account); + } + + function getMultipleValues() external view returns (uint256, uint256) { + if (shouldFail) { + revert MockFailure(); + } + return (value, value * 2); + } +} + +contract MockTarget { + uint256 public lastValue; + address public lastSender; + uint256 public lastEthValue; + bytes public lastCalldata; + bool public shouldFail; + + event CallReceived(uint256 value, address sender, uint256 ethValue); + + function setShouldFail(bool _shouldFail) external { + shouldFail = _shouldFail; + } + + function processValue(uint256 _value) external payable { + if (shouldFail) { + revert TargetFailure(); + } + lastValue = _value; + lastSender = msg.sender; + lastEthValue = msg.value; + lastCalldata = msg.data; + emit CallReceived(_value, msg.sender, msg.value); + } + + function processMultipleValues( + uint256 _value1, + uint256 _value2 + ) external payable { + if (shouldFail) { + revert TargetFailure(); + } + lastValue = _value1 + _value2; + lastSender = msg.sender; + lastEthValue = msg.value; + lastCalldata = msg.data; + emit CallReceived(_value1 + _value2, msg.sender, msg.value); + } + + function processComplexData( + uint256 _amount, + address /* _token */, + uint256 _deadline + ) external payable { + if (shouldFail) { + revert TargetFailure(); + } + lastValue = _amount + _deadline; + lastSender = msg.sender; + lastEthValue = msg.value; + lastCalldata = msg.data; + emit CallReceived(_amount + _deadline, msg.sender, msg.value); + } +} + +contract MockPriceOracle { + mapping(address => uint256) public prices; + bool public shouldFail; + + function setPrice(address token, uint256 price) external { + prices[token] = price; + } + + function setShouldFail(bool _shouldFail) external { + shouldFail = _shouldFail; + } + + function getPrice(address token) external view returns (uint256) { + if (shouldFail) { + revert OracleFailure(); + } + return prices[token]; + } + + function calculateMinAmount( + address token, + uint256 amount, + uint256 slippageBps + ) external view returns (uint256) { + if (shouldFail) { + revert OracleFailure(); + } + uint256 price = prices[token]; + if (price == 0) { + revert PriceNotSet(); + } + + return (amount * (10000 - slippageBps)) / 10000; + } +} + +contract TestRelayFacet is RelayFacet { + constructor( + address _relayReceiver, + address _relaySolver + ) RelayFacet(_relayReceiver, _relaySolver) {} + + function addDex(address _dex) external { + LibAllowList.addAllowedContract(_dex); + } + + function setFunctionApprovalBySignature(bytes4 _signature) external { + LibAllowList.addAllowedSelector(_signature); + } +} + +contract PatcherTest is TestBase { + event CallReceived(uint256 value, address sender, uint256 ethValue); + + Patcher internal patcher; + MockValueSource internal valueSource; + MockTarget internal target; + ERC20 internal token; + MockPriceOracle internal priceOracle; + TestRelayFacet internal relayFacet; + + address internal constant RELAY_RECEIVER = + 0xa5F565650890fBA1824Ee0F21EbBbF660a179934; + uint256 internal privateKey = 0x1234567890; + address internal relaySolver; + + function setUp() public { + patcher = new Patcher(); + valueSource = new MockValueSource(); + target = new MockTarget(); + token = new ERC20("Test Token", "TEST", 18); + priceOracle = new MockPriceOracle(); + + relaySolver = vm.addr(privateKey); + relayFacet = new TestRelayFacet(RELAY_RECEIVER, relaySolver); + } + + // Tests basic single value patching into calldata + function test_ExecuteWithDynamicPatches_Success() public { + uint256 dynamicValue = 12345; + valueSource.setValue(dynamicValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(dynamicValue, address(patcher), 0); + + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), dynamicValue); + assertEq(target.lastSender(), address(patcher)); + assertEq(target.lastEthValue(), 0); + } + + // Tests patching with ETH value transfer + function test_ExecuteWithDynamicPatches_WithEthValue() public { + uint256 dynamicValue = 54321; + uint256 ethValue = 1 ether; + + valueSource.setValue(dynamicValue); + vm.deal(address(patcher), ethValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(dynamicValue, address(patcher), ethValue); + + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + ethValue, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), dynamicValue); + assertEq(target.lastEthValue(), ethValue); + } + + // Tests patching same value to multiple positions in calldata + function test_ExecuteWithDynamicPatches_MultipleOffsets() public { + uint256 dynamicValue = 98765; + valueSource.setValue(dynamicValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processMultipleValues.selector, + uint256(0), + uint256(0) + ); + + uint256[] memory offsets = new uint256[](2); + offsets[0] = 4; + offsets[1] = 36; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(dynamicValue * 2, address(patcher), 0); + + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), dynamicValue * 2); + } + + // Tests patching different values from different sources + function test_ExecuteWithMultiplePatches_Success() public { + uint256 value1 = 11111; + uint256 value2 = 22222; + + MockValueSource valueSource2 = new MockValueSource(); + valueSource.setValue(value1); + valueSource2.setValue(value2); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processMultipleValues.selector, + uint256(0), + uint256(0) + ); + + address[] memory valueSources = new address[](2); + valueSources[0] = address(valueSource); + valueSources[1] = address(valueSource2); + + bytes[] memory valueGetters = new bytes[](2); + valueGetters[0] = abi.encodeWithSelector( + valueSource.getValue.selector + ); + valueGetters[1] = abi.encodeWithSelector( + valueSource2.getValue.selector + ); + + uint256[][] memory offsetGroups = new uint256[][](2); + offsetGroups[0] = new uint256[](1); + offsetGroups[0][0] = 4; + offsetGroups[1] = new uint256[](1); + offsetGroups[1][0] = 36; + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(value1 + value2, address(patcher), 0); + + patcher.executeWithMultiplePatches( + valueSources, + valueGetters, + address(target), + 0, + originalCalldata, + offsetGroups, + false + ); + + assertEq(target.lastValue(), value1 + value2); + } + + // Tests delegatecall execution mode + function test_ExecuteWithDynamicPatches_Delegatecall() public { + uint256 dynamicValue = 77777; + valueSource.setValue(dynamicValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectEmit(true, true, true, true, address(patcher)); + emit CallReceived(dynamicValue, address(this), 0); + + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + true + ); + } + + // Tests oracle/source failure handling + function testRevert_ExecuteWithDynamicPatches_FailedToGetDynamicValue() + public + { + valueSource.setShouldFail(true); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectRevert(Patcher.FailedToGetDynamicValue.selector); + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + } + + // Tests invalid offset bounds checking + function testRevert_ExecuteWithDynamicPatches_InvalidPatchOffset() public { + uint256 dynamicValue = 12345; + valueSource.setValue(dynamicValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = originalCalldata.length; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectRevert(Patcher.InvalidPatchOffset.selector); + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + } + + // Tests input validation for array length mismatches + function testRevert_ExecuteWithMultiplePatches_MismatchedArrayLengths() + public + { + address[] memory valueSources = new address[](2); + valueSources[0] = address(valueSource); + valueSources[1] = address(valueSource); + + bytes[] memory valueGetters = new bytes[](1); + valueGetters[0] = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + uint256[][] memory offsetGroups = new uint256[][](2); + offsetGroups[0] = new uint256[](1); + offsetGroups[1] = new uint256[](1); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + vm.expectRevert(Patcher.MismatchedArrayLengths.selector); + patcher.executeWithMultiplePatches( + valueSources, + valueGetters, + address(target), + 0, + originalCalldata, + offsetGroups, + false + ); + } + + // Tests ERC20 balance patching in realistic scenario + function test_ExecuteWithDynamicPatches_TokenBalance() public { + address holder = address(0x1234); + uint256 balance = 1000 ether; + token.mint(holder, balance); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processComplexData.selector, + uint256(0), + address(token), + block.timestamp + 1 hours + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + token.balanceOf.selector, + holder + ); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived( + balance + block.timestamp + 1 hours, + address(patcher), + 0 + ); + + patcher.executeWithDynamicPatches( + address(token), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), balance + block.timestamp + 1 hours); + } + + // Tests target contract failure handling + function testRevert_ExecuteWithDynamicPatches_TargetCallFailure() public { + uint256 dynamicValue = 12345; + valueSource.setValue(dynamicValue); + target.setShouldFail(true); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectRevert(); + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + } + + // Tests no-op patching with empty offsets + function test_ExecuteWithDynamicPatches_EmptyOffsets() public { + uint256 dynamicValue = 12345; + valueSource.setValue(dynamicValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(99999) + ); + + uint256[] memory offsets = new uint256[](0); + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(99999, address(patcher), 0); + + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), 99999); + } + + // Tests overwriting same position with multiple patches + function test_ExecuteWithMultiplePatches_SameOffset() public { + uint256 value1 = 11111; + uint256 value2 = 22222; + + MockValueSource valueSource2 = new MockValueSource(); + valueSource.setValue(value1); + valueSource2.setValue(value2); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + address[] memory valueSources = new address[](2); + valueSources[0] = address(valueSource); + valueSources[1] = address(valueSource2); + + bytes[] memory valueGetters = new bytes[](2); + valueGetters[0] = abi.encodeWithSelector( + valueSource.getValue.selector + ); + valueGetters[1] = abi.encodeWithSelector( + valueSource2.getValue.selector + ); + + uint256[][] memory offsetGroups = new uint256[][](2); + offsetGroups[0] = new uint256[](1); + offsetGroups[0][0] = 4; + offsetGroups[1] = new uint256[](1); + offsetGroups[1][0] = 4; + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(value2, address(patcher), 0); + + patcher.executeWithMultiplePatches( + valueSources, + valueGetters, + address(target), + 0, + originalCalldata, + offsetGroups, + false + ); + + assertEq(target.lastValue(), value2); + } + + // Tests zero value patching edge case + function test_ExecuteWithDynamicPatches_ZeroValue() public { + uint256 dynamicValue = 0; + valueSource.setValue(dynamicValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(12345) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(0, address(patcher), 0); + + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), 0); + } + + // Tests maximum uint256 value patching edge case + function test_ExecuteWithDynamicPatches_MaxValue() public { + uint256 dynamicValue = type(uint256).max; + valueSource.setValue(dynamicValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(type(uint256).max, address(patcher), 0); + + patcher.executeWithDynamicPatches( + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), type(uint256).max); + } + + // Tests price oracle integration with RelayFacet for dynamic minAmount + function test_ExecuteWithDynamicPatches_RelayFacetMinAmount() public { + uint256 tokenPrice = 2000 * 1e18; + uint256 slippageBps = 300; + priceOracle.setPrice(address(token), tokenPrice); + + ILiFi.BridgeData memory bridgeData = ILiFi.BridgeData({ + transactionId: bytes32("test-tx-id"), + bridge: "relay", + integrator: "TestIntegrator", + referrer: address(0x1234), + sendingAssetId: address(token), + receiver: address(0x5678), + minAmount: 0, + destinationChainId: 8453, + hasSourceSwaps: false, + hasDestinationCall: false + }); + + RelayFacet.RelayData memory relayData = RelayFacet.RelayData({ + requestId: bytes32("test-request-id"), + nonEVMReceiver: bytes32(0), + receivingAssetId: bytes32(uint256(uint160(address(0xDEF)))), + signature: "" + }); + + relayData.signature = signData(bridgeData, relayData); + + uint256 bridgeAmount = 1000 ether; + uint256 expectedMinAmount = (bridgeAmount * (10000 - slippageBps)) / + 10000; + + token.mint(address(patcher), expectedMinAmount); + + vm.prank(address(patcher)); + token.approve(address(relayFacet), expectedMinAmount); + + uint256 relaySolverBalanceBefore = token.balanceOf(relaySolver); + + bytes memory originalCalldata = abi.encodeWithSelector( + relayFacet.startBridgeTokensViaRelay.selector, + bridgeData, + relayData + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 260; + + bytes memory valueGetter = abi.encodeWithSelector( + priceOracle.calculateMinAmount.selector, + address(token), + bridgeAmount, + slippageBps + ); + + ILiFi.BridgeData memory expectedBridgeData = bridgeData; + expectedBridgeData.minAmount = expectedMinAmount; + + vm.expectEmit(true, true, true, true, address(relayFacet)); + emit LiFiTransferStarted(expectedBridgeData); + + patcher.executeWithDynamicPatches( + address(priceOracle), + valueGetter, + address(relayFacet), + 0, + originalCalldata, + offsets, + false + ); + + uint256 relaySolverBalanceAfter = token.balanceOf(relaySolver); + assertEq( + relaySolverBalanceAfter, + relaySolverBalanceBefore + expectedMinAmount + ); + } + + // Tests balance-based bridging with RelayFacet + function test_ExecuteWithDynamicPatches_RelayFacetTokenBalance() public { + uint256 tokenBalance = 500 ether; + + ILiFi.BridgeData memory bridgeData = ILiFi.BridgeData({ + transactionId: bytes32("balance-patch-tx"), + bridge: "relay", + integrator: "TestIntegrator", + referrer: address(0x1234), + sendingAssetId: address(token), + receiver: address(1337), + minAmount: 0, + destinationChainId: 8453, + hasSourceSwaps: false, + hasDestinationCall: false + }); + + RelayFacet.RelayData memory relayData = RelayFacet.RelayData({ + requestId: bytes32("balance-patch-request"), + nonEVMReceiver: bytes32(0), + receivingAssetId: bytes32(uint256(uint160(address(0xDEF)))), + signature: "" + }); + + relayData.signature = signData(bridgeData, relayData); + + token.mint(address(patcher), tokenBalance); + + vm.prank(address(patcher)); + token.approve(address(relayFacet), tokenBalance); + + uint256 relaySolverBalanceBefore = token.balanceOf(relaySolver); + + bytes memory originalCalldata = abi.encodeWithSelector( + relayFacet.startBridgeTokensViaRelay.selector, + bridgeData, + relayData + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 260; + + bytes memory valueGetter = abi.encodeWithSelector( + token.balanceOf.selector, + patcher + ); + + ILiFi.BridgeData memory expectedBridgeData = bridgeData; + expectedBridgeData.minAmount = tokenBalance; + + vm.expectEmit(true, true, true, true, address(relayFacet)); + emit LiFiTransferStarted(expectedBridgeData); + + patcher.executeWithDynamicPatches( + address(token), + valueGetter, + address(relayFacet), + 0, + originalCalldata, + offsets, + false + ); + + uint256 relaySolverBalanceAfter = token.balanceOf(relaySolver); + assertEq( + relaySolverBalanceAfter, + relaySolverBalanceBefore + tokenBalance + ); + } + + // Tests oracle failure in bridge context + function testRevert_ExecuteWithDynamicPatches_RelayFacetOracleFailure() + public + { + priceOracle.setShouldFail(true); + + ILiFi.BridgeData memory bridgeData = ILiFi.BridgeData({ + transactionId: bytes32("fail-tx"), + bridge: "relay", + integrator: "TestIntegrator", + referrer: address(0x1234), + sendingAssetId: address(token), + receiver: address(0x5678), + minAmount: 0, + destinationChainId: 8453, + hasSourceSwaps: false, + hasDestinationCall: false + }); + + RelayFacet.RelayData memory relayData = RelayFacet.RelayData({ + requestId: bytes32("fail-request"), + nonEVMReceiver: bytes32(0), + receivingAssetId: bytes32(uint256(uint160(address(0xDEF)))), + signature: "" + }); + + relayData.signature = signData(bridgeData, relayData); + + uint256 relaySolverBalanceBefore = token.balanceOf(relaySolver); + + bytes memory originalCalldata = abi.encodeWithSelector( + relayFacet.startBridgeTokensViaRelay.selector, + bridgeData, + relayData + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 260; + + bytes memory valueGetter = abi.encodeWithSelector( + priceOracle.calculateMinAmount.selector, + address(token), + 1000 ether, + 300 + ); + + vm.expectRevert(Patcher.FailedToGetDynamicValue.selector); + patcher.executeWithDynamicPatches( + address(priceOracle), + valueGetter, + address(relayFacet), + 0, + originalCalldata, + offsets, + false + ); + + uint256 relaySolverBalanceAfter = token.balanceOf(relaySolver); + assertEq(relaySolverBalanceAfter, relaySolverBalanceBefore); + } + + function signData( + ILiFi.BridgeData memory _bridgeData, + RelayFacet.RelayData memory _relayData + ) internal view returns (bytes memory) { + bytes32 message = keccak256( + abi.encodePacked( + "\x19Ethereum Signed Message:\n32", + keccak256( + abi.encodePacked( + _relayData.requestId, + block.chainid, + bytes32(uint256(uint160(address(relayFacet)))), + bytes32(uint256(uint160(_bridgeData.sendingAssetId))), + _getMappedChainId(_bridgeData.destinationChainId), + _bridgeData.receiver == LibAsset.NON_EVM_ADDRESS + ? _relayData.nonEVMReceiver + : bytes32(uint256(uint160(_bridgeData.receiver))), + _relayData.receivingAssetId + ) + ) + ) + ); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, message); + bytes memory signature = abi.encodePacked(r, s, v); + return signature; + } + + function _getMappedChainId( + uint256 chainId + ) internal pure returns (uint256) { + if (chainId == 20000000000001) { + return 8253038; + } + + if (chainId == 1151111081099710) { + return 792703809; + } + + return chainId; + } + + // Tests token deposit + execution workflow + function test_DepositAndExecuteWithDynamicPatches_Success() public { + uint256 dynamicValue = 12345; + valueSource.setValue(dynamicValue); + + address user = address(0x1234); + uint256 tokenBalance = 1000 ether; + token.mint(user, tokenBalance); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.prank(user); + token.approve(address(patcher), tokenBalance); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(dynamicValue, address(patcher), 0); + + vm.prank(user); + patcher.depositAndExecuteWithDynamicPatches( + address(token), + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), dynamicValue); + assertEq(target.lastSender(), address(patcher)); + assertEq(target.lastEthValue(), 0); + + assertEq(token.balanceOf(address(patcher)), tokenBalance); + assertEq(token.balanceOf(user), 0); + } + + // Tests deposit with multiple patches workflow + function test_DepositAndExecuteWithMultiplePatches_Success() public { + uint256 value1 = 11111; + uint256 value2 = 22222; + + MockValueSource valueSource2 = new MockValueSource(); + valueSource.setValue(value1); + valueSource2.setValue(value2); + + address user = address(0x5678); + uint256 tokenBalance = 500 ether; + token.mint(user, tokenBalance); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processMultipleValues.selector, + uint256(0), + uint256(0) + ); + + address[] memory valueSources = new address[](2); + valueSources[0] = address(valueSource); + valueSources[1] = address(valueSource2); + + bytes[] memory valueGetters = new bytes[](2); + valueGetters[0] = abi.encodeWithSelector( + valueSource.getValue.selector + ); + valueGetters[1] = abi.encodeWithSelector( + valueSource2.getValue.selector + ); + + uint256[][] memory offsetGroups = new uint256[][](2); + offsetGroups[0] = new uint256[](1); + offsetGroups[0][0] = 4; + offsetGroups[1] = new uint256[](1); + offsetGroups[1][0] = 36; + + vm.prank(user); + token.approve(address(patcher), tokenBalance); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(value1 + value2, address(patcher), 0); + + vm.prank(user); + patcher.depositAndExecuteWithMultiplePatches( + address(token), + valueSources, + valueGetters, + address(target), + 0, + originalCalldata, + offsetGroups, + false + ); + + assertEq(target.lastValue(), value1 + value2); + + assertEq(token.balanceOf(address(patcher)), tokenBalance); + assertEq(token.balanceOf(user), 0); + } + + // Tests deposit with zero balance edge case + function testRevert_DepositAndExecuteWithDynamicPatches_ZeroBalance() + public + { + uint256 dynamicValue = 12345; + valueSource.setValue(dynamicValue); + + address user = address(0x9999); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(dynamicValue, address(patcher), 0); + + vm.prank(user); + patcher.depositAndExecuteWithDynamicPatches( + address(token), + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), dynamicValue); + + assertEq(token.balanceOf(address(patcher)), 0); + assertEq(token.balanceOf(user), 0); + } + + // Tests insufficient approval handling + function testRevert_DepositAndExecuteWithDynamicPatches_NoApproval() + public + { + uint256 dynamicValue = 12345; + valueSource.setValue(dynamicValue); + + address user = address(0xABCD); + uint256 tokenBalance = 1000 ether; + token.mint(user, tokenBalance); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.prank(user); + vm.expectRevert(); + patcher.depositAndExecuteWithDynamicPatches( + address(token), + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + } + + // Tests partial approval edge case + function testRevert_DepositAndExecuteWithDynamicPatches_PartialApproval() + public + { + uint256 dynamicValue = 12345; + valueSource.setValue(dynamicValue); + + address user = address(0xEF12); + uint256 tokenBalance = 1000 ether; + uint256 approvalAmount = 500 ether; + token.mint(user, tokenBalance); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.prank(user); + token.approve(address(patcher), approvalAmount); + + vm.prank(user); + vm.expectRevert(); + patcher.depositAndExecuteWithDynamicPatches( + address(token), + address(valueSource), + valueGetter, + address(target), + 0, + originalCalldata, + offsets, + false + ); + } + + // Tests that users can send native tokens with executeWithDynamicPatches + function test_ExecuteWithDynamicPatches_WithNativeToken() public { + uint256 dynamicValue = 12345; + uint256 ethValue = 1 ether; + valueSource.setValue(dynamicValue); + + address user = address(0xABCD); + vm.deal(user, ethValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + // User sends native tokens with the call + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(dynamicValue, address(patcher), ethValue); + + vm.prank(user); + patcher.executeWithDynamicPatches{ value: ethValue }( + address(valueSource), + valueGetter, + address(target), + ethValue, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), dynamicValue); + assertEq(target.lastSender(), address(patcher)); + assertEq(target.lastEthValue(), ethValue); + + // Verify that the user's native tokens were spent + assertEq(user.balance, 0); + } + + // Tests that depositAndExecuteWithDynamicPatches can handle native tokens + function test_DepositAndExecuteWithDynamicPatches_WithNativeToken() + public + { + uint256 dynamicValue = 54321; + uint256 ethValue = 0.5 ether; + valueSource.setValue(dynamicValue); + + address user = address(0x1234); + uint256 tokenBalance = 1000 ether; + token.mint(user, tokenBalance); + vm.deal(user, ethValue); + + bytes memory originalCalldata = abi.encodeWithSelector( + target.processValue.selector, + uint256(0) + ); + + uint256[] memory offsets = new uint256[](1); + offsets[0] = 4; + + bytes memory valueGetter = abi.encodeWithSelector( + valueSource.getValue.selector + ); + + vm.prank(user); + token.approve(address(patcher), tokenBalance); + + vm.expectEmit(true, true, true, true, address(target)); + emit CallReceived(dynamicValue, address(patcher), ethValue); + + vm.prank(user); + patcher.depositAndExecuteWithDynamicPatches{ value: ethValue }( + address(token), + address(valueSource), + valueGetter, + address(target), + ethValue, + originalCalldata, + offsets, + false + ); + + assertEq(target.lastValue(), dynamicValue); + assertEq(target.lastSender(), address(patcher)); + assertEq(target.lastEthValue(), ethValue); + + assertEq(token.balanceOf(address(patcher)), tokenBalance); + assertEq(token.balanceOf(user), 0); + assertEq(user.balance, 0); + } +}