diff --git a/.env.example b/.env.example index 058cde75..50871ed5 100644 --- a/.env.example +++ b/.env.example @@ -11,10 +11,8 @@ DEPLOY_SALT="" # Localhost (chainId: X) LOCALHOST_NODE_URI="http://127.0.0.1:8545" -LOCALHOST_MNEMONIC="" LOCALHOST_ETHERSCAN_API_KEY="" # (chainId: ) _NODE_URI="" -_MNEMONIC="" _ETHERSCAN_API_KEY="" diff --git a/.github/workflows/ci-deep.yml b/.github/workflows/ci-deep.yml index f445eced..5c5cfed2 100644 --- a/.github/workflows/ci-deep.yml +++ b/.github/workflows/ci-deep.yml @@ -89,9 +89,9 @@ jobs: - name: Run Foundry tests run: bun foundry:test env: - ETH_NODE_URI_OPTIMISM: ${{ secrets.ETH_NODE_URI_OPTIMISM }} - ETH_NODE_URI_ARBITRUM: ${{ secrets.ETH_NODE_URI_ARBITRUM }} - ETH_NODE_URI_MAINNET: ${{ secrets.ETH_NODE_URI_MAINNET }} + OPTIMISM_NODE_URI: ${{ secrets.ETH_NODE_URI_OPTIMISM }} + ARBITRUM_NODE_URI: ${{ secrets.ETH_NODE_URI_ARBITRUM }} + BASE_NODE_URI: ${{ secrets.ETH_NODE_URI_MAINNET }} FOUNDRY_FUZZ_RUNS: ${{ github.event.inputs.fuzzRuns || '10000' }} - name: 'Add test summary' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d786e7e6..55341953 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,9 +72,9 @@ jobs: run: bun foundry:test env: FOUNDRY_FUZZ_RUNS: '5000' - ETH_NODE_URI_OPTIMISM: ${{ secrets.ETH_NODE_URI_OPTIMISM }} - ETH_NODE_URI_ARBITRUM: ${{ secrets.ETH_NODE_URI_ARBITRUM }} - ETH_NODE_URI_MAINNET: ${{ secrets.ETH_NODE_URI_MAINNET }} + OPTIMISM_NODE_URI: ${{ secrets.ETH_NODE_URI_OPTIMISM }} + ARBITRUM_NODE_URI: ${{ secrets.ETH_NODE_URI_ARBITRUM }} + BASE_NODE_URI: ${{ secrets.ETH_NODE_URI_MAINNET }} - name: 'Add test summary' run: | diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0126b89b..9d32172e 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,9 +24,9 @@ jobs: - name: 'Generate the coverage report using the unit and the integration tests' run: 'bun ci:coverage' env: - ETH_NODE_URI_OPTIMISM: ${{ secrets.ETH_NODE_URI_OPTIMISM }} - ETH_NODE_URI_ARBITRUM: ${{ secrets.ETH_NODE_URI_ARBITRUM }} - ETH_NODE_URI_MAINNET: ${{ secrets.ETH_NODE_URI_MAINNET }} + OPTIMISM_NODE_URI: ${{ secrets.ETH_NODE_URI_OPTIMISM }} + ARBITRUM_NODE_URI: ${{ secrets.ETH_NODE_URI_ARBITRUM }} + BASE_NODE_URI: ${{ secrets.ETH_NODE_URI_MAINNET }} - name: 'Upload coverage report to Codecov' uses: 'codecov/codecov-action@v3' diff --git a/.gitignore b/.gitignore index d18d8467..2ea17176 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,4 @@ bin /out /zkout /cache-forge +/transactions diff --git a/bun.lock b/bun.lock index 16075e12..67f8446b 100644 --- a/bun.lock +++ b/bun.lock @@ -5,6 +5,7 @@ "name": "merkl-contracts", "devDependencies": { "@angleprotocol/sdk": "^2.41.43", + "@merkl/registry": "latest", "@openzeppelin/contracts": "^4.9.0", "@openzeppelin/contracts-upgradeable": "4.9.0", "forge-std": "github:foundry-rs/forge-std#v1.9.4", @@ -22,7 +23,7 @@ "@angleprotocol/sdk": ["@angleprotocol/sdk@2.41.43", "https://npm.pkg.github.com/download/@angleprotocol/sdk/2.41.43/84459336530fb89cbc0b18f6488745d8aad74032", { "dependencies": { "@apollo/client": "^3.12.2", "@typechain/ethers-v5": "^10.0.0", "@types/lodash": "^4.17.13", "axios": "^1.7.7", "bun-types": "^1.1.27", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", "cross-fetch": "^4.0.0", "ethers": "^5.6.4", "graphql": "^16.9.0", "graphql-request": "^3.6.1", "jsbi": "^4.3.0", "keccak256": "^1.0.6", "lodash": "^4.17.21", "merkletreejs": "^0.3.10", "p-limit": "^6.2.0", "pino": "^9.6.0", "reflect-metadata": "^0.2.2", "tiny-invariant": "^1.1.0", "typechain": "^8.3.2", "viem": "2.28.0" } }, "sha512-2LNSQW3FRMwusTKgVUxIWBhpvFO9wMq4hJM3krwa8SXWnn4msdSUFFoJanwI5AZTVrwCngs9gYTpaAIvUMS5WA=="], - "@apollo/client": ["@apollo/client@3.13.8", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@wry/caches": "^1.0.0", "@wry/equality": "^0.5.6", "@wry/trie": "^0.5.0", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", "optimism": "^0.18.0", "prop-types": "^15.7.2", "rehackt": "^0.1.0", "symbol-observable": "^4.0.0", "ts-invariant": "^0.10.3", "tslib": "^2.3.0", "zen-observable-ts": "^1.2.5" }, "peerDependencies": { "graphql": "^15.0.0 || ^16.0.0", "graphql-ws": "^5.5.5 || ^6.0.3", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc", "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" }, "optionalPeers": ["graphql-ws", "react", "react-dom", "subscriptions-transport-ws"] }, "sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg=="], + "@apollo/client": ["@apollo/client@3.13.9", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@wry/caches": "^1.0.0", "@wry/equality": "^0.5.6", "@wry/trie": "^0.5.0", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", "optimism": "^0.18.0", "prop-types": "^15.7.2", "rehackt": "^0.1.0", "symbol-observable": "^4.0.0", "ts-invariant": "^0.10.3", "tslib": "^2.3.0", "zen-observable-ts": "^1.2.5" }, "peerDependencies": { "graphql": "^15.0.0 || ^16.0.0", "graphql-ws": "^5.5.5 || ^6.0.3", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc", "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" }, "optionalPeers": ["graphql-ws", "react", "react-dom", "subscriptions-transport-ws"] }, "sha512-RStSzQfL1XwL6/NWd7W8avhGQYTgPCtJ+qHkkTTSj9Upp3VVm6Oppv81YWdXG1FgEpDPW4hvCrTUELdcC4inCQ=="], "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], @@ -96,7 +97,7 @@ "@graphql-typed-document-node/core": ["@graphql-typed-document-node/core@3.2.0", "", { "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="], - "@merkl/registry": ["@merkl/registry@0.1.14", "", {}, "sha512-rs0QrZlPHeGPhZN7e0FX5vXu8AGMTE2EWPtg1Ir0ciTTNlc3ZKQ0so4gw3sPP2orhiXn9RuUy3KAMj+0YWakSQ=="], + "@merkl/registry": ["@merkl/registry@0.6.0", "", {}, "sha512-l6pTuSU0uK1NUBp66XyouSw8FmPplQtWOJYtehIxNptkX6omdXfI0KpXdmoKSoxEX52IjABe8zpaHR90JjsrEQ=="], "@noble/curves": ["@noble/curves@1.8.2", "", { "dependencies": { "@noble/hashes": "1.7.2" } }, "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g=="], @@ -166,25 +167,21 @@ "@sentry/utils": ["@sentry/utils@5.30.0", "", { "dependencies": { "@sentry/types": "5.30.0", "tslib": "^1.9.3" } }, "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww=="], - "@solidity-parser/parser": ["@solidity-parser/parser@0.20.1", "", {}, "sha512-58I2sRpzaQUN+jJmWbHfbWf9AKfzqCI8JAdFB0vbyY+u8tBRcuTt9LxzasvR0LGQpcRv97eyV7l61FQ3Ib7zVw=="], + "@solidity-parser/parser": ["@solidity-parser/parser@0.20.2", "", {}, "sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA=="], "@typechain/ethers-v5": ["@typechain/ethers-v5@10.2.1", "", { "dependencies": { "lodash": "^4.17.15", "ts-essentials": "^7.0.1" }, "peerDependencies": { "@ethersproject/abi": "^5.0.0", "@ethersproject/providers": "^5.0.0", "ethers": "^5.1.3", "typechain": "^8.1.1", "typescript": ">=4.3.0" } }, "sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A=="], - "@types/bn.js": ["@types/bn.js@5.2.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q=="], - "@types/glob": ["@types/glob@7.2.0", "", { "dependencies": { "@types/minimatch": "*", "@types/node": "*" } }, "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA=="], "@types/lodash": ["@types/lodash@4.17.20", "", {}, "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA=="], - "@types/lru-cache": ["@types/lru-cache@5.1.1", "", {}, "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw=="], - "@types/minimatch": ["@types/minimatch@6.0.0", "", { "dependencies": { "minimatch": "*" } }, "sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA=="], - "@types/node": ["@types/node@24.0.14", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw=="], + "@types/node": ["@types/node@24.3.0", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow=="], "@types/prettier": ["@types/prettier@2.7.3", "", {}, "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA=="], - "@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="], + "@types/react": ["@types/react@19.1.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg=="], "@types/validator": ["@types/validator@13.15.2", "", {}, "sha512-y7pa/oEJJ4iGYBxOpfAKn5b9+xuihvzDVnC/OSvlVnGxVg0pOqmjiMafiJ1KVNQEaPZf9HsEp5icEwGg8uIe5Q=="], @@ -244,7 +241,7 @@ "atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="], - "axios": ["axios@1.10.0", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw=="], + "axios": ["axios@1.11.0", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA=="], "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], @@ -274,7 +271,7 @@ "buffer-reverse": ["buffer-reverse@1.0.1", "", {}, "sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg=="], - "bun-types": ["bun-types@1.2.18", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-04+Eha5NP7Z0A9YgDAzMk5PHR16ZuLVa83b26kH5+cp1qZW4F6FmAURngE7INf4tKOvCE69vYvDEwoNl1tGiWw=="], + "bun-types": ["bun-types@1.2.20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="], "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], @@ -406,7 +403,7 @@ "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], - "fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], @@ -416,11 +413,11 @@ "flat": ["flat@5.0.2", "", { "bin": { "flat": "cli.js" } }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="], - "follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="], + "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], "forge-std": ["forge-std@github:foundry-rs/forge-std#1eea5ba", {}, "foundry-rs-forge-std-1eea5ba"], - "form-data": ["form-data@4.0.3", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA=="], + "form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="], "fp-ts": ["fp-ts@1.19.3", "", {}, "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg=="], @@ -462,7 +459,7 @@ "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=="], - "hardhat": ["hardhat@2.25.0", "", { "dependencies": { "@ethereumjs/util": "^9.1.0", "@ethersproject/abi": "^5.1.2", "@nomicfoundation/edr": "^0.11.1", "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", "adm-zip": "^0.4.16", "aggregate-error": "^3.0.0", "ansi-escapes": "^4.3.0", "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-yBiA74Yj3VnTRj7lhnn8GalvBdvsMOqTKRrRATSy/2v0VIR2hR0Jcnmfn4aQBLtGAnr3Q2c8CxL0g3LYegUp+g=="], + "hardhat": ["hardhat@2.26.3", "", { "dependencies": { "@ethereumjs/util": "^9.1.0", "@ethersproject/abi": "^5.1.2", "@nomicfoundation/edr": "^0.11.3", "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", "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-gBfjbxCCEaRgMCRgTpjo1CEoJwqNPhyGMMVHYZJxoQ3LLftp2erSVf8ZF6hTQC0r2wst4NcqNmLWqMnHg1quTw=="], "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], @@ -558,7 +555,7 @@ "levn": ["levn@0.3.0", "", { "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA=="], - "libphonenumber-js": ["libphonenumber-js@1.12.10", "", {}, "sha512-E91vHJD61jekHHR/RF/E83T/CMoaLXT7cwYA75T4gim4FZjnM6hbJjVIGg7chqlSqRsSvQ3izGmOjHy1SQzcGQ=="], + "libphonenumber-js": ["libphonenumber-js@1.12.12", "", {}, "sha512-aWVR6xXYYRvnK0v/uIwkf5Lthq9Jpn0N8TISW/oDTWlYB2sOimuiLn9Q26aUw4KxkJoiT8ACdiw44Y8VwKFIfQ=="], "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], @@ -664,11 +661,11 @@ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - "picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], "pify": ["pify@4.0.1", "", {}, "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="], - "pino": ["pino@9.7.0", "", { "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg=="], + "pino": ["pino@9.9.0", "", { "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-zxsRIQG9HzG+jEljmvmZupOMDUQ0Jpj0yAgE28jQvvrdYTlEaiGwelJpdndMl/MBuRr70heIj83QyqJUWaU8mQ=="], "pino-abstract-transport": ["pino-abstract-transport@2.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw=="], @@ -830,7 +827,7 @@ "typechain": ["typechain@8.3.2", "", { "dependencies": { "@types/prettier": "^2.1.1", "debug": "^4.3.1", "fs-extra": "^7.0.0", "glob": "7.1.7", "js-sha3": "^0.8.0", "lodash": "^4.17.15", "mkdirp": "^1.0.4", "prettier": "^2.3.1", "ts-command-line-args": "^2.2.0", "ts-essentials": "^7.0.1" }, "peerDependencies": { "typescript": ">=4.3.0" }, "bin": { "typechain": "dist/cli/cli.js" } }, "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q=="], - "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], + "typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="], "typical": ["typical@4.0.0", "", {}, "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw=="], @@ -838,7 +835,7 @@ "undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="], - "undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="], + "undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="], "universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], @@ -942,7 +939,7 @@ "graphql-request/cross-fetch": ["cross-fetch@3.2.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q=="], - "graphql-request/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=="], + "graphql-request/form-data": ["form-data@3.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.35" } }, "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ=="], "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=="], diff --git a/foundry.toml b/foundry.toml index 81d25503..c49a1d83 100644 --- a/foundry.toml +++ b/foundry.toml @@ -9,9 +9,8 @@ cache_path = 'cache-forge' gas_reports = ["*"] optimizer_runs = 100 fs_permissions = [ - { access = "read", path = "./node_modules/@angleprotocol/sdk/dist/src/registry/registry.json" }, - { access = "write", path = "./transaction.json" }, - { access = "write", path = "./transactions.json" } + { access = "read", path = "./node_modules/@merkl/registry/dist/src/registry.json" }, + { access = "write", path = "./transactions" }, ] solc = "0.8.25" @@ -28,7 +27,7 @@ cache_path = 'cache-forge' gas_reports = ["*"] optimizer_runs = 100 fs_permissions = [ - { access = "read", path = "./node_modules/@angleprotocol/sdk/dist/src/registry/registry.json" }, + { access = "read", path = "./node_modules/@merkl/registry/dist/src/registry.json" }, { access = "write", path = "./transaction.json" }, { access = "write", path = "./transactions.json" } ] @@ -49,9 +48,8 @@ mainnet = "${MAINNET_NODE_URI}" polygon = "${POLYGON_NODE_URI}" fantom = "${FANTOM_NODE_URI}" optimism = "${OPTIMISM_NODE_URI}" -arbitrum = "${ETH_NODE_URI_ARBITRUM}" +arbitrum = "${ARBITRUM_NODE_URI}" avalanche = "${AVALANCHE_NODE_URI}" -aurora = "${AURORA_NODE_URI}" bsc = "${BSC_NODE_URI}" gnosis = "${GNOSIS_NODE_URI}" polygonzkevm = "${POLYGONZKEVM_NODE_URI}" @@ -74,16 +72,14 @@ sei = "${SEI_NODE_URI}" celo = "${CELO_NODE_URI}" fraxtal = "${FRAXTAL_NODE_URI}" astar = "${ASTAR_NODE_URI}" -astarzkevm = "${ASTARZKEVM_NODE_URI}" rootstock = "${ROOTSTOCK_NODE_URI}" moonbeam = "${MOONBEAM_NODE_URI}" skale = "${SKALE_NODE_URI}" worldchain = "${WORLDCHAIN_NODE_URI}" lisk = "${LISK_NODE_URI}" etherlink = "${ETHERLINK_NODE_URI}" -arthera = "${ARTHERA_NODE_URI}" swell = "${SWELL_NODE_URI}" -fork = "${ETH_NODE_URI_FORK}" +fork = "${FORK_NODE_URI}" sonic = "${SONIC_NODE_URI}" corn = "${CORN_NODE_URI}" ink = "${INK_NODE_URI}" @@ -97,57 +93,57 @@ hyperevm = "${HYPEREVM_NODE_URI}" hemi="${HEMI_NODE_URI}" xdc="${XDC_NODE_URI}" katana="${KATANA_NODE_URI}" +tac="${TAC_NODE_URI}" [etherscan] localhost = { url = "http://localhost:4000", key = "none" } -mainnet = { chainId = 1, key = "${MAINNET_ETHERSCAN_API_KEY}", url = "https://api.etherscan.io/api" } -polygon = { chainId = 137, key = "${POLYGON_ETHERSCAN_API_KEY}", url = "https://api.polygonscan.com/api" } -fantom = { chainId = 250, key = "${FANTOM_ETHERSCAN_API_KEY}", url = "https://api.ftmscan.com/api" } -optimism = { chainId = 10, key = "${OPTIMISM_ETHERSCAN_API_KEY}", url = "https://api-optimistic.etherscan.io/api" } -arbitrum = { chainId = 42161, key = "${ARBITRUM_ETHERSCAN_API_KEY}", url = "https://api.arbiscan.io/api" } -avalanche = { chainId = 43114, key = "${AVALANCHE_ETHERSCAN_API_KEY}", url = "https://api.avascan.info/v2/network/mainnet/evm/43114/etherscan" } -aurora = { chainId = 1313161554, key = "${AURORA_ETHERSCAN_API_KEY}", url = "http://localhost:4000" } -bsc = { chainId = 56, key = "${BSC_ETHERSCAN_API_KEY}", url = "https://api.bscscan.com/api" } -gnosis = { chainId = 100, key = "${GNOSIS_ETHERSCAN_API_KEY}", url = "https://api.gnosisscan.io/api" } -polygonzkevm = { chainId = 1101, key = "${POLYGONZKEVM_ETHERSCAN_API_KEY}", url = "https://api-zkevm.polygonscan.com/api" } -base = { chainId = 8453, key = "${BASE_ETHERSCAN_API_KEY}", url = "https://api.basescan.org/api" } -bob = { chainId = 60808, key = "${BOB_ETHERSCAN_API_KEY}", url = "https://explorer.gobob.xyz/api" } -linea = { chainId = 59144, key = "${LINEA_ETHERSCAN_API_KEY}", url = "https://api.lineascan.build/api" } -zksync = { chainId = 324, key = "${ZKSYNC_ETHERSCAN_API_KEY}", url = "https://explorer.sepolia.era.zksync.dev/contract_verification" } -mantle = { chainId = 5000, key = "${MANTLE_ETHERSCAN_API_KEY}", url = "https://explorer.mantle.xyz/api" } -blast = { chainId = 81457, key = "${BLAST_ETHERSCAN_API_KEY}", url = "https://api.blastscan.io/api" } -mode = { chainId = 34443, key = "${MODE_ETHERSCAN_API_KEY}", url = "https://api.routescan.io/v2/network/mainnet/evm/34443/etherscan/api" } -thundercore = { chainId = 108, key = "${THUNDERCORE_ETHERSCAN_API_KEY}", url = "" } -coredao = { chainId = 1116, key = "${COREDAO_ETHERSCAN_API_KEY}", url = "https://openapi.coredao.org/api" } -xlayer = { chainId = 196, key = "${XLAYER_ETHERSCAN_API_KEY}", url = "https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/XLAYER" } -taiko = { chainId = 167000, key = "${TAIKO_ETHERSCAN_API_KEY}", url = "https://api.taikoscan.io/api" } -fuse = { chainId = 122, key = "${FUSE_ETHERSCAN_API_KEY}", url = "https://explorer.fuse.io/api" } -immutable = { chainId = 13371, key = "${IMMUTABLE_ETHERSCAN_API_KEY}", url = "https://immutable-mainnet.blockscout.com/api" } -scroll = { chainId = 534352, key = "${SCROLL_ETHERSCAN_API_KEY}", url = "https://api.scrollscan.com/api" } -manta = { chainId = 169, key = "${MANTA_ETHERSCAN_API_KEY}", url = "https://pacific-explorer.manta.network/api" } -sei = { chainId = 1329, key = "${SEI_ETHERSCAN_API_KEY}", url = "https://seitrace.com/pacific-1/api" } -celo = { chainId = 42220, key = "${CELO_ETHERSCAN_API_KEY}", url = "https://api.celoscan.io/api" } -fraxtal = { chainId = 252, key = "${FRAXTAL_ETHERSCAN_API_KEY}", url = "https://api.fraxscan.io/api" } -astar = { chainId = 592, key = "${ASTAR_ETHERSCAN_API_KEY}", url = "https://astar.blockscout.com/api/" } -astarzkevm = { chainId = 3776, key = "${ASTARZKEVM_ETHERSCAN_API_KEY}", url = "https://astar-zkevm.explorer.startale.com/api" } -rootstock = { chainId = 30, key = "${ROOTSTOCK_ETHERSCAN_API_KEY}", url = "https://rootstock.blockscout.com/api/" } -moonbeam = { chainId = 1284, key = "${MOONBEAM_ETHERSCAN_API_KEY}", url = "https://api-moonbase.moonscan.io/api" } -skale = { chainId = 2046399126, key = "${SKALE_ETHERSCAN_API_KEY}", url = "https://internal-hubs.explorer.mainnet.skalenodes.com:10001/api" } -worldchain = { chainId = 480, key = "${WORLDCHAIN_ETHERSCAN_API_KEY}", url = "https://worldchain-mainnet.explorer.alchemy.com/api" } -lisk = { chainId = 1135, key = "${LISK_ETHERSCAN_API_KEY}", url = "https://blockscout.lisk.com/api/" } -etherlink = { chainId = 42793, key = "${ETHERLINK_ETHERSCAN_API_KEY}", url= "https://explorer.etherlink.com/api" } -arthera = { chainId = 10242, key = "${ARTHERA_ETHERSCAN_API_KEY}", url = "https://explorer.arthera.net/api/" } -swell = { chainId = 1923, key = "${SWELL_ETHERSCAN_API_KEY}", url = "https://explorer.swellnetwork.io:443/api/" } -sonic = { chainId = 146, key = "${SONIC_ETHERSCAN_API_KEY}", url = "https://api.sonicscan.org/api/" } -corn = { chainId = 21000000, key = "${CORN_ETHERSCAN_API_KEY}", url = "https://api.routescan.io/v2/network/mainnet/evm/21000000/etherscan"} -ink = { chainId = 57073, key = "${INK_ETHERSCAN_API_KEY}", url = "https://explorer.inkonchain.com/api" } -ronin = { chainId = 2020, key = "${RONIN_ETHERSCAN_API_KEY}", url = "https://sourcify.roninchain.com/server/" } -flow = { chainId = 747, key = "${FLOW_ETHERSCAN_API_KEY}", url = "https://api.flowscan.io/api" } -berachain = { chainId = 80094, key = "${BERACHAIN_ETHERSCAN_API_KEY}", url = "https://api.berascan.com/api" } -nibiru = { chainId = 6900, key = "${NIBIRU_ETHERSCAN_API_KEY}", url = "https://api.routescan.io/v2/network/mainnet/evm/6900/etherscan/api" } -zircuit = { chainId = 48900, key = "${ZIRCUIT_ETHERSCAN_API_KEY}", url = "https://sourcify.dev/server" } -apechain = { chainId = 33139, key = "${APECHAIN_ETHERSCAN_API_KEY}", url = "https://api.apescan.io/api" } -hyperevm = { chainId = 999, key = "${HYPEREVM_ETHERSCAN_API_KEY}", url = "https://hyperliquid.cloud.blockscout.com/api" } -hemi = { chainId = 43111, key = "${HEMI_ETHERSCAN_API_KEY}", url = "https://explorer.hemi.xyz/api/" } -xdc = { chainId = 50, key = "${XDC_ETHERSCAN_API_KEY}", url = "https://api.xdcscan.com/api/" } -katana = {chainId = 747474, key = "${$KATANA_ETHERSCAN_API_KEY}", url = "https://explorer.katanarpc.com/" } +mainnet = { chainId = 1, key = "${MAINNET_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_1}" } +polygon = { chainId = 137, key = "${POLYGON_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_137}" } +fantom = { chainId = 250, key = "${FANTOM_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_250}" } +optimism = { chainId = 10, key = "${OPTIMISM_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_10}" } +arbitrum = { chainId = 42161, key = "${ARBITRUM_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_42161}" } +avalanche = { chainId = 43114, key = "${AVALANCHE_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_43114}" } +bsc = { chainId = 56, key = "${BSC_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_56}" } +gnosis = { chainId = 100, key = "${GNOSIS_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_100}" } +polygonzkevm = { chainId = 1101, key = "${POLYGONZKEVM_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_1101}" } +base = { chainId = 8453, key = "${BASE_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_8453}" } +bob = { chainId = 60808, key = "${BOB_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_60808}" } +linea = { chainId = 59144, key = "${LINEA_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_59144}" } +zksync = { chainId = 324, key = "${ZKSYNC_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_324}" } +mantle = { chainId = 5000, key = "${MANTLE_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_5000}" } +blast = { chainId = 81457, key = "${BLAST_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_81457}" } +mode = { chainId = 34443, key = "${MODE_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_34443}" } +thundercore = { chainId = 108, key = "${THUNDERCORE_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_108}" } +coredao = { chainId = 1116, key = "${COREDAO_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_1116}" } +xlayer = { chainId = 196, key = "${XLAYER_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_196}" } +taiko = { chainId = 167000, key = "${TAIKO_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_167000}" } +fuse = { chainId = 122, key = "${FUSE_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_122}" } +immutable = { chainId = 13371, key = "${IMMUTABLE_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_13371}" } +scroll = { chainId = 534352, key = "${SCROLL_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_534352}" } +manta = { chainId = 169, key = "${MANTA_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_169}" } +sei = { chainId = 1329, key = "${SEI_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_1329}" } +celo = { chainId = 42220, key = "${CELO_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_42220}" } +fraxtal = { chainId = 252, key = "${FRAXTAL_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_252}" } +astar = { chainId = 592, key = "${ASTAR_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_592}" } +rootstock = { chainId = 30, key = "${ROOTSTOCK_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_30}" } +moonbeam = { chainId = 1284, key = "${MOONBEAM_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_1284}" } +skale = { chainId = 2046399126, key = "${SKALE_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_2046399126}" } +worldchain = { chainId = 480, key = "${WORLDCHAIN_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_480}" } +lisk = { chainId = 1135, key = "${LISK_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_1135}" } +etherlink = { chainId = 42793, key = "${ETHERLINK_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_42793}" } +swell = { chainId = 1923, key = "${SWELL_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_1923}" } +sonic = { chainId = 146, key = "${SONIC_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_146}" } +corn = { chainId = 21000000, key = "${CORN_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_21000000}" } +ink = { chainId = 57073, key = "${INK_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_57073}" } +ronin = { chainId = 2020, key = "${RONIN_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_2020}" } +flow = { chainId = 747, key = "${FLOW_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_747}" } +berachain = { chainId = 80094, key = "${BERACHAIN_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_80094}" } +nibiru = { chainId = 6900, key = "${NIBIRU_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_6900}" } +zircuit = { chainId = 48900, key = "${ZIRCUIT_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_48900}" } +apechain = { chainId = 33139, key = "${APECHAIN_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_33139}" } +hyperevm = { chainId = 999, key = "${HYPEREVM_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_999}" } +hemi = { chainId = 43111, key = "${HEMI_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_43111}" } +xdc = { chainId = 50, key = "${XDC_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_50}" } +katana = {chainId = 747474, key = "${KATANA_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_747474}" } +tac = {chainId = 239, key = "${TAC_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_239}" } +plasma = {chainId = 9745, key = "${$PLASMA_ETHERSCAN_API_KEY}", url = "${VERIFIER_URL_9745}" } \ No newline at end of file diff --git a/helpers/foundryMultiChainScript.sh b/helpers/foundryMultiChainScript.sh index f200242d..d6e9c2e0 100755 --- a/helpers/foundryMultiChainScript.sh +++ b/helpers/foundryMultiChainScript.sh @@ -9,7 +9,7 @@ function usage { # Get list of chain IDs where DistributionCreator is deployed function get_available_chains() { - local registry_file="node_modules/@angleprotocol/sdk/dist/src/registry/registry.json" + local registry_file="node_modules/@merkl/registry/dist/src/registry.json" if [ ! -f "$registry_file" ]; then echo "Registry file not found!" exit 1 @@ -113,7 +113,7 @@ function main { fi # Path to the registry file - registry_file="node_modules/@angleprotocol/sdk/dist/src/registry/registry.json" + registry_file="node_modules/@merkl/registry/dist/src/registry.json" if [ ! -f "$registry_file" ]; then echo "Registry file not found!" diff --git a/package.json b/package.json index 00bc003f..6529adb3 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "url": "https://github.com/AngleProtocol/merkl-contracts/issues" }, "devDependencies": { + "@merkl/registry": "latest", "@angleprotocol/sdk": "^2.41.43", "@openzeppelin/contracts": "^4.9.0", "@openzeppelin/contracts-upgradeable": "4.9.0", diff --git a/scripts/Disputer.s.sol b/scripts/Disputer.s.sol index 259dd095..d3fdc35c 100644 --- a/scripts/Disputer.s.sol +++ b/scripts/Disputer.s.sol @@ -8,6 +8,9 @@ import { JsonReader } from "@utils/JsonReader.sol"; import { BaseScript } from "./utils/Base.s.sol"; import { Disputer } from "../contracts/Disputer.sol"; import { Distributor } from "../contracts/Distributor.sol"; +import { MockToken } from "../contracts/mock/MockToken.sol"; +import { TokensUtils } from "./utils/TokensUtils.sol"; +import { CreateXConstants } from "./utils/CreateXConstants.sol"; // Base contract with shared constants and utilities contract DisputerScript is BaseScript, JsonReader { @@ -210,3 +213,58 @@ contract ToggleDispute is DisputerScript { console.log("Toggled dispute for:", _reason); } } + +contract DeployWithCreate is DisputerScript, TokensUtils, CreateXConstants { + function run(address disputeToken) external broadcast { + uint256 chainId = block.chainid; + address distributor = readAddress(chainId, "Distributor"); + + deployDisputer(distributor, disputeToken); + } + + function deployDisputer(address distributor, address disputeToken) public returns (address) { + console.log("\n=== Deploying Disputer ==="); + + bytes32 salt = vm.envBytes32("DEPLOY_SALT"); + + // Check if CREATEX contract is deployed + address disputer; + // if (CREATEX.code.length == 0) { + address CREATE2_DEPLOYER = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + // if (CREATE2_DEPLOYER.code.length != 0) { + + // // Deploy using the standard Deterministic CREATE2 deployer and a deterministic salt + // disputer = address(new Disputer{ salt: salt }(broadcaster, DISPUTER_WHITELIST, Distributor(distributor))); + // } else { + // // Classic deployment if CREATE2 deployer is not deployed + // // disputer = address(new Disputer(broadcaster, DISPUTER_WHITELIST, Distributor(distributor))); + // } + // } else { + // Deploy using CreateX + // Create initialization bytecode + bytes + memory bytecode = hex"60806040523480156200001157600080fd5b506040516200137738038062001377833981016040819052620000349162000322565b6200003f33620001b3565b600180546001600160a01b0319166001600160a01b0383169081179091556040805163c748d26160e01b8152905163c748d261916004808201926020929091908290030181865afa15801562000099573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000bf91906200041f565b60405163095ea7b360e01b81526001600160a01b0383811660048301526000196024830152919091169063095ea7b3906044016020604051808303816000875af115801562000112573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000138919062000446565b50815160005b818110156200019d576001600260008684815181106200016257620001626200046a565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016200013e565b50620001a98462000203565b5050505062000480565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6200020d62000286565b6001600160a01b038116620002785760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6200028381620001b3565b50565b6000546001600160a01b03163314620002e25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200026f565b565b6001600160a01b03811681146200028357600080fd5b80516200030781620002e4565b919050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156200033857600080fd5b83516200034581620002e4565b602085810151919450906001600160401b03808211156200036557600080fd5b818701915087601f8301126200037a57600080fd5b8151818111156200038f576200038f6200030c565b8060051b604051601f19603f83011681018181108582111715620003b757620003b76200030c565b60405291825284820192508381018501918a831115620003d657600080fd5b938501935b82851015620003ff57620003ef85620002fa565b84529385019392850192620003db565b8097505050505050506200041660408501620002fa565b90509250925092565b6000602082840312156200043257600080fd5b81516200043f81620002e4565b9392505050565b6000602082840312156200045957600080fd5b815180151581146200043f57600080fd5b634e487b7160e01b600052603260045260246000fd5b610ee780620004906000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80639b19251a11610081578063ca85e5d01161005b578063ca85e5d0146101bb578063e43252d7146101ce578063f2fde38b146101e157600080fd5b80639b19251a14610155578063bfe1092814610188578063c1075329146101a857600080fd5b806375619ab5116100b257806375619ab5146100eb5780638ab1d681146100fe5780638da5cb5b1461011157600080fd5b80631c20fadd146100ce578063715018a6146100e3575b600080fd5b6100e16100dc366004610c1d565b6101f4565b005b6100e161029b565b6100e16100f9366004610c5e565b6102af565b6100e161010c366004610c5e565b61055e565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610178610163366004610c5e565b60026020526000908152604090205460ff1681565b604051901515815260200161014c565b60015461012b9073ffffffffffffffffffffffffffffffffffffffff1681565b6100e16101b6366004610c82565b6105b2565b6100e16101c9366004610cdd565b610659565b6100e16101dc366004610c5e565b6109f2565b6100e16101ef366004610c5e565b610a49565b6101fc610b05565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610271573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102959190610dac565b50505050565b6102a3610b05565b6102ad6000610b86565b565b6102b7610b05565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c748d2616040518163ffffffff1660e01b8152600401602060405180830381865afa158015610324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103489190610dce565b6001546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000602482015291169063095ea7b3906044016020604051808303816000875af11580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190610dac565b50600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc748d261000000000000000000000000000000000000000000000000000000008152905163c748d261916004808201926020929091908290030181865afa15801561047c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a09190610dce565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6024830152919091169063095ea7b3906044016020604051808303816000875af1158015610536573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055a9190610dac565b5050565b610566610b05565b73ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6105ba610b05565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610614576040519150601f19603f3d011682016040523d82523d6000602084013e610619565b606091505b5050905080610654576040517f27fcd9d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b3360009081526002602052604090205460ff166106a2576040517f584a793800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604080517fc748d261000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163c748d2619160048083019260209291908290030181865afa158015610712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107369190610dce565b90506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309454ba36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107cb9190610deb565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa15801561083b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085f9190610deb565b9050818110156109645773ffffffffffffffffffffffffffffffffffffffff83166323b872dd33306108918587610e04565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff938416600482015292909116602483015260448201526064016020604051808303816000875af115801561090a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092e9190610dac565b610964576040517fb1eb39bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546040517f2a25dd4100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632a25dd41906109ba908790600401610e44565b600060405180830381600087803b1580156109d457600080fd5b505af11580156109e8573d6000803e3d6000fd5b5050505050505050565b6109fa610b05565b73ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b610a51610b05565b73ffffffffffffffffffffffffffffffffffffffff8116610af9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b0281610b86565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610af0565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b0257600080fd5b600080600060608486031215610c3257600080fd5b8335610c3d81610bfb565b92506020840135610c4d81610bfb565b929592945050506040919091013590565b600060208284031215610c7057600080fd5b8135610c7b81610bfb565b9392505050565b60008060408385031215610c9557600080fd5b8235610ca081610bfb565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610cef57600080fd5b813567ffffffffffffffff80821115610d0757600080fd5b818401915084601f830112610d1b57600080fd5b813581811115610d2d57610d2d610cae565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610d7357610d73610cae565b81604052828152876020848701011115610d8c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610dbe57600080fd5b81518015158114610c7b57600080fd5b600060208284031215610de057600080fd5b8151610c7b81610bfb565b600060208284031215610dfd57600080fd5b5051919050565b81810381811115610e3e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b60006020808352835180602085015260005b81811015610e7257858101830151858201604001528201610e56565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509291505056fea26469706673582212202c48aee5de4959ef518786fa36afffd4b4a0c2f4af9e25741d18037fdf60170b64736f6c63430008180033000000000000000000000000a9ddd91249dfdd450e81e1c56ab60e1a6265170100000000000000000000000000000000000000000000000000000000000000600000000000000000000000003ef3d8ba38ebe18db133cec108f4d14ce00dd9ae0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000ea05f9001fbdea6d4280879f283ff9d0b282060e0000000000000000000000000dd2ea40a3561c309c03b96108e78d06e8a1a99b000000000000000000000000f4c94b2fdc2efa4ad4b831f312e7ef74890705da"; + + // Deploy using the specified CREATE2 deployer and a deterministic salt + bytes memory callData = abi.encodeWithSignature("deployCreate2(bytes32,bytes)", salt, bytecode); + (bool success, bytes memory returnData) = CREATEX.call(callData); + + require(success, "CREATE2 deployment failed"); + disputer = address(uint160(uint256(bytes32(returnData)))); + + console.log("Disputer:", disputer); + + // // Transfer ownership to multisig + // console.log("Transferred Disputer ownership to multisig:", multisig); + // Disputer(disputer).transferOwnership(multisig); + + // // Send dispute tokens to disputer + // uint256 amount = 100 * 10 ** MockToken(disputeToken).decimals(); + // if (MockToken(disputeToken).balanceOf(broadcaster) >= amount) { + // transferERC20Tokens(disputer, 100 * 10 ** MockToken(disputeToken).decimals(), disputeToken); + // console.log("Sent dispute tokens to disputer:", 100 * 10 ** MockToken(disputeToken).decimals()); + // } + + return address(disputer); + } +} diff --git a/scripts/DistributionCreator.s.sol b/scripts/DistributionCreator.s.sol index af9efacf..58fd3b1d 100644 --- a/scripts/DistributionCreator.s.sol +++ b/scripts/DistributionCreator.s.sol @@ -226,7 +226,6 @@ contract SetRewardTokenMinAmounts is DistributionCreatorScript { uint256 chainId = block.chainid; address creatorAddress = readAddress(chainId, "DistributionCreator"); - address creatorAddress = 0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd; DistributionCreator(creatorAddress).setRewardTokenMinAmounts(_tokens, _amounts); console.log("Minimum amounts updated for %s tokens", _tokens.length); @@ -365,106 +364,17 @@ contract CreateCampaign is DistributionCreatorScript { function run() external broadcast { bytes memory campaignData; // MODIFY THESE VALUES TO SET YOUR DESIRED CAMPAIGN PARAMETERS - // address targetToken = address(0xEe9BFf933aDD313C4289E98dA80fEfbF9d5Cd9Ba); - // uint32 campaignType = 22; - // uint32 subCampaignType = 0; - // uint256 tokenId = 0; - // address[] memory whitelist = new address[](0); - // address[] memory blacklist = new address[](0); - // string memory url = "https://app.hyperdrive.box/market/100/0xEe9BFf933aDD313C4289E98dA80fEfbF9d5Cd9Ba"; - // bytes[] memory hooks = new bytes[](0); - // string memory apr = "1"; - // bool targetTokenPricing = true; - // bool rewardTokenPricing = false; - // bytes memory campaignData = abi.encode( - // targetToken, - // subCampaignType, - // tokenId, - // whitelist, - // blacklist, - // url, - // hooks, - // apr, - // targetTokenPricing, - // rewardTokenPricing - // ); - // // - - // address targetToken = address(0x324395D5d835F84a02A75Aa26814f6fD22F25698); - // uint32 campaignType = 21; - // uint32 subCampaignType = 2; - // uint256 tokenId = 0; - // address[] memory whitelist = new address[](0); - // address[] memory blacklist = new address[](0); - // string memory url = "https://app.hyperdrive.box/market/1/0x324395D5d835F84a02A75Aa26814f6fD22F25698"; - // bytes[] memory hooks = new bytes[](0); - // campaignData = abi.encode(targetToken, subCampaignType, tokenId, whitelist, blacklist, url, hooks); - // address rewardToken = address(0x6B175474E89094C44Da98b954EedeAC495271d0F); - - address targetToken = address(0xEe9BFf933aDD313C4289E98dA80fEfbF9d5Cd9Ba); - uint32 campaignType = 21; - uint32 subCampaignType = 2; - uint256 tokenId = 0; - address[] memory whitelist = new address[](0); - address[] memory blacklist = new address[](0); - string memory url = "https://app.hyperdrive.box/market/100/0xEe9BFf933aDD313C4289E98dA80fEfbF9d5Cd9Ba"; - bytes[] memory hooks = new bytes[](0); - campaignData = abi.encode(targetToken, subCampaignType, tokenId, whitelist, blacklist, url, hooks); - address rewardToken = address(0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d); - - // - - // address targetToken = address(0x004626A008B1aCdC4c74ab51644093b155e59A23); - // uint32 campaignType = 1; - // address[] memory whitelist = new address[](0); - // address[] memory blacklist = new address[](0); - // string memory url = ""; - // bytes[] memory forwarders = new bytes[](0); - // bytes[] memory hooks = new bytes[](0); - // bytes memory campaignData = abi.encode(targetToken, whitelist, blacklist, url, forwarders, hooks, hex""); - - // uint32 campaignType = 26; - // { - // address baseToken = address(0); - // address quoteToken = 0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34; - // uint256 poolIdx = 420; - // bool isOutOfRangeIncentivized = false; - // uint32 weightFees = 2000; - // uint32 weightToken0 = 3000; - // uint32 weightToken1 = 5000; - // address[] memory whitelist = new address[](0); - // address[] memory blacklist = new address[](0); - // string - // memory url = "https://ambient.finance/trade/market/chain=0x783&tokenA=0x0000000000000000000000000000000000000000&tokenB=0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34"; - // bytes[] memory hooks = new bytes[](0); - // bytes[] memory forwarders = new bytes[](0); - // campaignData = abi.encode( - // baseToken, - // quoteToken, - // poolIdx, - // isOutOfRangeIncentivized, - // weightFees, - // weightToken0, - // weightToken1, - // whitelist, - // blacklist, - // url, - // forwarders, - // hooks, - // hex"" - // ); - // } - // END + address rewardToken = address(0xB63B9f0eb4A6E6f191529D71d4D88cc8900Df2C9); CampaignParameters memory campaign = CampaignParameters({ campaignId: bytes32(0), creator: address(0), rewardToken: rewardToken, - amount: 5000 * 10 ** (IERC20Metadata(rewardToken).decimals()), - campaignType: campaignType, - startTimestamp: 1740063600, - duration: 30 days, - campaignData: campaignData + amount: 9867825382083116891581, + campaignType: 56, + startTimestamp: 1752764400, + duration: 385200, + campaignData: hex"00000000000000000000000084bbc0be5a6f831a4e2c28a2f3b892c70acaa5b3000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000009fee01e948353e0897968a3ea955815aaa49f58d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }); _run(campaign); } @@ -894,3 +804,109 @@ contract SetRewardTokenMinAmountsDistributor is DistributionCreatorScript { DistributionCreator(creatorAddress).setRewardTokenMinAmounts(tokens, minAmounts); } } + +// SetFeesMultichain script +contract SetFeesMultichain is DistributionCreatorScript { + struct FailedChain { + string network; + uint256 chainId; + string reason; + } + + function externalReadAddress(uint256 chainId, string memory key) public view returns (address) { + return readAddress(chainId, key); + } + + function run() external { + // Set default fees to 0 and campaign fees to 3% (30,000,000 in 9 decimals) + uint256 defaultFees = 0; + uint256 campaignFees = 5000000; // 0.5% + + // Get all networks from foundry.toml + string[2][] memory networks = vm.rpcUrls(); + + // Track failed chains + FailedChain[] memory failedChains = new FailedChain[](networks.length); + uint256 failedCount = 0; + uint256 successCount = 0; + + for (uint256 i = 0; i < networks.length; i++) { + string memory network = networks[i][0]; + + // Skip localhost and fork + if ( + keccak256(abi.encodePacked(network)) == keccak256(abi.encodePacked("localhost")) || + keccak256(abi.encodePacked(network)) == keccak256(abi.encodePacked("fork")) || + keccak256(abi.encodePacked(network)) == keccak256(abi.encodePacked("zksync")) || + keccak256(abi.encodePacked(network)) == keccak256(abi.encodePacked("nibiru")) // No multisig deployed + ) { + continue; + } + + // // Create fork for this network + vm.createSelectFork(network); + uint256 chainId = block.chainid; + address creatorAddress = readAddress(chainId, "Merkl.DistributionCreator"); + + // Create contract instances to reuse existing logic + // SetFees setFeesContract = new SetFees(); + // SetCampaignFees setCampaignFeesContract = new SetCampaignFees(); + + // Set default fees using existing contract + // TODO: Instead of broadcasting, we should just write the transaction to the json file + bytes memory setFeesPayload = abi.encodeWithSelector(DistributionCreator.setFees.selector, defaultFees); + + // address safe = readAddress(chainId, "AngleLabs"); + // console.log("Safe address: %s", safe); + address safe = readAddress(chainId, "AngleLabs"); + _serializeJson( + chainId, + creatorAddress, // target address (the DistributionCreator proxy) + 0, // value + setFeesPayload, // setFees call + Operation.Call, // standard call (not delegate) + hex"", // signature + safe // safe address + ); + console.log("Default fees transaction serialized for %s (chain %s)", network, chainId); + successCount++; + + // // Set campaign fees for each type using existing contract + // if (DistributionCreator(creatorAddress).campaignSpecificFees(27) != campaignFees) { + // console.log("Setting campaign fees for type 27 to %s", campaignFees); + // try setCampaignFeesContract.run(27, campaignFees) { + // // Success + // console.log("Fees updated on %s (chain %s)", network, chainId); + // successCount++; + // } catch (bytes memory err) { + // console.log("Failed to set campaign fees for type %s on %s", 27, network); + // failedChains[failedCount] = FailedChain(network, chainId, string(err)); + // failedCount++; + // vm.stopBroadcast(); + // } + // } + } + + // Display summary + console.log(""); + console.log("=== MULTICHAIN FEE SETTING SUMMARY ==="); + console.log("Successful chains: %s", successCount); + console.log("Failed chains: %s", failedCount); + + if (failedCount > 0) { + console.log(""); + console.log("Failed chains details:"); + for (uint256 i = 0; i < failedCount; i++) { + console.log( + "- %s (Chain ID: %s) - Reason: %s", + failedChains[i].network, + failedChains[i].chainId, + failedChains[i].reason + ); + } + } + + console.log(""); + console.log("Multichain fee setting completed!"); + } +} diff --git a/scripts/Distributor.s.sol b/scripts/Distributor.s.sol index f4afb71d..9bc109ed 100644 --- a/scripts/Distributor.s.sol +++ b/scripts/Distributor.s.sol @@ -6,10 +6,13 @@ import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { JsonReader } from "@utils/JsonReader.sol"; import { ITransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import { ProxyAdmin } from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import { ChainUtils, IMultiChainScript } from "./utils/ChainUtils.s.sol"; import { BaseScript } from "./utils/Base.s.sol"; import { Distributor, MerkleTree } from "../contracts/Distributor.sol"; import { IAccessControlManager } from "../contracts/interfaces/IAccessControlManager.sol"; +import { AccessControlManager } from "../contracts/AccessControlManager.sol"; // Base contract with shared utilities contract DistributorScript is BaseScript, JsonReader {} @@ -324,3 +327,66 @@ contract BuildUpgradeToPayload is DistributorScript { return readAddress(chainId, key); } } + +contract DisputeCheck is DistributorScript, ChainUtils { + function run() external broadcast { + uint256 chainId = block.chainid; + address _distributor = readAddress(chainId, "Distributor"); + address _core = readAddress(chainId, "CoreMerkl"); + address _multisig = readAddress(chainId, "Multisig"); + address _proxyAdmin = readAddress(chainId, "ProxyAdmin"); + + // Now we can call verifyRegistryAddresses directly! + verifyRegistryAddresses(_distributor, _core, _multisig, _proxyAdmin); + + uint256 disputeAmount = Distributor(_distributor).disputeAmount(); + address disputeToken = address(Distributor(_distributor).disputeToken()); + console.log("Dispute amount:", disputeAmount); + console.log("Dispute token:", disputeToken); + + // deployCreateX(); + if (disputeAmount == 0 && disputeToken == address(0)) { + disputeAmount = 100 * 10 ** 6; + disputeToken = address(0x79A02482A880bCE3F13e09Da970dC34db4CD24d1); // worldchain 480 + + bytes memory setDisputeTokenPayload = abi.encodeWithSelector( + Distributor.setDisputeToken.selector, + disputeToken + ); + + // address safe = readAddress(chainId, "AngleLabs"); + // console.log("Safe address: %s", safe); + address safe = readAddress(chainId, "Multisig"); + _serializeJson( + chainId, + _distributor, // target address (the DistributionCreator proxy) + 0, // value + setDisputeTokenPayload, // setFees call + Operation.Call, // standard call (not delegate) + hex"", // signature + safe // safe address + ); + // Distributor(distributor).setDisputeAmount(disputeAmount); + // Distributor(distributor).setDisputeToken(IERC20(disputeToken)); + // Distributor(distributor).setDisputePeriod(1); + } + } +} + +// New MultiChain version of the existing DisputeCheck +contract DisputeCheckMultiChain is DistributorScript, ChainUtils { + function run() external { + // Run dispute check across all chains without using address(this) + bytes memory emptyData = ""; + executeAcrossChains(address(0), emptyData, false); + } + + // Override the executeScript function to run our dispute check logic + function executeScript( + address /* scriptContract */, + bytes memory /* data */ + ) internal override returns (bool success, string memory errorReason) { + new DisputeCheck().run(); + return (true, ""); + } +} diff --git a/scripts/deployPullTokenWrapperWithAllow.s.sol b/scripts/deployPullTokenWrapperWithAllow.s.sol index 77fc5556..750f38ab 100644 --- a/scripts/deployPullTokenWrapperWithAllow.s.sol +++ b/scripts/deployPullTokenWrapperWithAllow.s.sol @@ -41,7 +41,12 @@ contract DeployPullTokenWrapperWithAllow is BaseScript { // Initialize PullTokenWrapperWithAllow(address(proxy)).initialize(underlying, distributionCreator, minter, name, symbol); - DistributionCreator(distributionCreator).setRewardTokenMinAmounts([address(proxy)], [1e18]); // Set the minimum amount for the token wrapper + address[] memory tokens; + tokens[0] = address(proxy); + + uint256[] memory amounts; + amounts[0] = 1e18; + DistributionCreator(distributionCreator).setRewardTokenMinAmounts(tokens, amounts); // Set the minimum amount for the token wrapper vm.stopBroadcast(); } diff --git a/scripts/utils/Base.s.sol b/scripts/utils/Base.s.sol index 6f23005b..eaf29281 100644 --- a/scripts/utils/Base.s.sol +++ b/scripts/utils/Base.s.sol @@ -58,6 +58,11 @@ abstract contract BaseScript is Script { vm.stopBroadcast(); } + modifier fork(string memory network) { + vm.createSelectFork(vm.rpcUrl(network)); + _; + } + function _serializeJson( uint256 chainId, address to, @@ -89,6 +94,6 @@ abstract contract BaseScript is Script { } string memory finalJson = vm.serializeBytes(json, "data", data); - vm.writeJson(finalJson, "./transaction.json"); + vm.writeJson(finalJson, string.concat("./transactions/", vm.toString(chainId), ".json")); } } diff --git a/scripts/utils/ChainUtils.s.sol b/scripts/utils/ChainUtils.s.sol new file mode 100644 index 00000000..b17ca988 --- /dev/null +++ b/scripts/utils/ChainUtils.s.sol @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.17; + +import { console } from "forge-std/console.sol"; +import { ProxyAdmin } from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import { JsonReader } from "@utils/JsonReader.sol"; +import { BaseScript } from "./Base.s.sol"; + +// Interface for scripts that can be executed across chains +interface IMultiChainScript { + function executeOnChain() external; + function executeOnChain(bytes calldata data) external; +} + +contract ChainUtils is JsonReader { + struct FailedChain { + string network; + uint256 chainId; + string reason; + } + + struct ExecutionResult { + string network; + uint256 chainId; + bool success; + string reason; + bytes returnData; + } + + // Events for better tracking + event ChainExecutionStarted(string network, uint256 chainId); + event ChainExecutionCompleted(string network, uint256 chainId, bool success); + event ChainExecutionFailed(string network, uint256 chainId, string reason); + + function externalReadAddress(uint256 chainId, string memory key) public view returns (address) { + return readAddress(chainId, key); + } + + // Registry verification function + function verifyRegistryAddresses( + address _distributor, + address _core, + address _multisig, + address _proxyAdmin + ) public view { + bytes memory coreData; + (bool success, bytes memory returnData) = _distributor.staticcall(abi.encodeWithSignature("core()")); + if (success) { + coreData = returnData; + } else { + (bool success2, bytes memory returnData2) = _distributor.staticcall( + abi.encodeWithSignature("accessControlManager()") + ); + require(success2, "Invalid accessControlManager()"); + coreData = returnData2; + } + + // We need to skip the first 12 bytes (function selector + padding) to get the address + address core = address(uint160(uint256(bytes32(coreData)))); + bytes32 proxyAdminData = vm.load(core, 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103); + address proxyAdmin = address(uint160(uint256(proxyAdminData))); + address multisig = ProxyAdmin(proxyAdmin).owner(); + + if (core != _core) { + console.log("Core merkl mismatch for chain", block.chainid); + } + + if (proxyAdmin != _proxyAdmin) { + console.log("Proxy admin mismatch for chain", block.chainid); + } + + if (multisig != _multisig) { + console.log("Multisig mismatch for chain", block.chainid); + } + } + + // Multi-chain execution logic (can be used by script contracts that inherit this) + function executeAcrossChains(address scriptContract, bytes memory data, bool verificationOnly) internal { + // Get all networks from foundry.toml + string[2][] memory networks = vm.rpcUrls(); + + // Track results + ExecutionResult[] memory results = new ExecutionResult[](networks.length); + uint256 totalChains = 0; + uint256 successCount = 0; + uint256 failedCount = 0; + + if (verificationOnly) { + console.log("=== MULTICHAIN VERIFICATION STARTED ==="); + } else { + console.log("=== MULTICHAIN EXECUTION STARTED ==="); + } + + for (uint256 i = 0; i < networks.length; i++) { + string memory network = networks[i][0]; + + // Skip localhost, fork, and zksync + if ( + keccak256(abi.encodePacked(network)) == keccak256(abi.encodePacked("localhost")) || + keccak256(abi.encodePacked(network)) == keccak256(abi.encodePacked("fork")) || + keccak256(abi.encodePacked(network)) == keccak256(abi.encodePacked("zksync")) + ) { + continue; + } + + // Create fork for this network + bool forkSuccess = true; + try vm.createSelectFork(network) { + // Fork creation succeeded + } catch { + forkSuccess = false; + console.log("[FAILED] Failed to create fork for network:", network); + } + + if (forkSuccess) { + uint256 chainId = block.chainid; + emit ChainExecutionStarted(network, chainId); + + results[totalChains] = ExecutionResult({ + network: network, + chainId: chainId, + success: false, + reason: "", + returnData: "" + }); + + if (verificationOnly) { + // Perform registry verification + address _distributor = readAddress(chainId, "Distributor"); + address _core = readAddress(chainId, "CoreMerkl"); + address _multisig = readAddress(chainId, "Multisig"); + address _proxyAdmin = readAddress(chainId, "ProxyAdmin"); + + verifyRegistryAddresses(_distributor, _core, _multisig, _proxyAdmin); + results[totalChains].success = true; + successCount++; + console.log("[SUCCESS] Verification completed for", network); + console.log("Chain ID:", chainId); + } else { + // Execute script + (bool scriptSuccess, string memory errorReason) = executeScript(scriptContract, data); + + if (scriptSuccess) { + results[totalChains].success = true; + successCount++; + emit ChainExecutionCompleted(network, chainId, true); + console.log("[SUCCESS] Script execution completed for", network); + console.log("Chain ID:", chainId); + } else { + results[totalChains].reason = errorReason; + failedCount++; + emit ChainExecutionFailed(network, chainId, errorReason); + console.log("[FAILED] Script execution failed for", network); + console.log("Chain ID:", chainId); + console.log("Reason:", errorReason); + } + } + + totalChains++; + } + } + + // Display summary + displaySummary(results, totalChains, successCount, failedCount, verificationOnly); + } + + // Execute a specific script with error handling + function executeScript( + address scriptContract, + bytes memory data + ) internal virtual returns (bool success, string memory errorReason) { + if (scriptContract == address(0)) { + return (false, "Script contract cannot be zero address"); + } + + // Try different execution methods based on what the script supports + if (data.length > 0) { + // Try to call with data first + (bool success1, ) = scriptContract.call(abi.encodeWithSignature("executeOnChain(bytes)", data)); + if (success1) { + return (true, ""); + } + } + + // Fall back to parameterless execution + (bool success2, ) = scriptContract.call(abi.encodeWithSignature("executeOnChain()")); + + if (success2) { + return (true, ""); + } + + // If both fail, try calling the run() function directly + (bool success3, ) = scriptContract.call(abi.encodeWithSignature("run()")); + if (success3) { + return (true, ""); + } + + return (false, "All script execution methods failed"); + } + + // Execute script on a single chain + function executeOnSingleChain( + string calldata network, + address scriptContract, + bytes memory data + ) internal returns (bool success, string memory errorReason) { + try vm.createSelectFork(network) { + uint256 chainId = block.chainid; + console.log("Executing script on", network); + console.log("Chain ID:", chainId); + + return executeScript(scriptContract, data); + } catch { + return (false, "Failed to create fork for network"); + } + } + + function displaySummary( + ExecutionResult[] memory results, + uint256 totalChains, + uint256 successCount, + uint256 failedCount, + bool verificationOnly + ) internal pure { + console.log(""); + if (verificationOnly) { + console.log("=== MULTICHAIN VERIFICATION SUMMARY ==="); + } else { + console.log("=== MULTICHAIN EXECUTION SUMMARY ==="); + } + console.log("Total chains processed:", totalChains); + console.log("Successful chains:", successCount); + console.log("Failed chains:", failedCount); + + if (failedCount > 0) { + console.log(""); + console.log("Failed chains details:"); + for (uint256 i = 0; i < totalChains; i++) { + if (!results[i].success) { + console.log("- Network:", results[i].network); + console.log(" Chain ID:", results[i].chainId); + console.log(" Reason:", results[i].reason); + } + } + } + + console.log(""); + if (verificationOnly) { + console.log("Multichain verification completed!"); + } else { + console.log("Multichain execution completed!"); + } + } +} + +// Script contract for running ChainUtils operations +contract ChainUtilsScript is BaseScript, ChainUtils { + // Original verification-only run function + function run() external { + runVerification(); + } + + // Execute script across all chains + function runScript(address scriptContract) external { + bytes memory emptyData = ""; + executeAcrossChains(scriptContract, emptyData, false); + } + + function runScript(address scriptContract, bytes memory data) external { + executeAcrossChains(scriptContract, data, false); + } + + // Execute script on a single specific chain + function runScriptOnChain(string calldata network, address scriptContract) external { + bytes memory emptyData = ""; + (bool success, string memory errorReason) = executeOnSingleChain(network, scriptContract, emptyData); + + if (success) { + console.log("[SUCCESS] Script executed successfully on", network); + } else { + console.log("[FAILED] Script failed on", network); + console.log("Reason:", errorReason); + } + } + + function runScriptOnChain(string calldata network, address scriptContract, bytes memory data) external { + (bool success, string memory errorReason) = executeOnSingleChain(network, scriptContract, data); + + if (success) { + console.log("[SUCCESS] Script executed successfully on", network); + } else { + console.log("[FAILED] Script failed on", network); + console.log("Reason:", errorReason); + } + } + + // Verify registries across all chains + function runVerification() public { + bytes memory emptyData = ""; + executeAcrossChains(address(0), emptyData, true); + } + + // Verify registry on a single chain + function runVerificationOnChain(string calldata network) external { + vm.createSelectFork(network); + uint256 chainId = block.chainid; + + address _distributor = readAddress(chainId, "Distributor"); + address _core = readAddress(chainId, "CoreMerkl"); + address _multisig = readAddress(chainId, "Multisig"); + address _proxyAdmin = readAddress(chainId, "ProxyAdmin"); + + verifyRegistryAddresses(_distributor, _core, _multisig, _proxyAdmin); + console.log("[SUCCESS] Registry verification completed for", network); + } +} diff --git a/test/unit/DistributionCreator.t.sol b/test/unit/DistributionCreator.t.sol index 0f67b16c..437dd833 100644 --- a/test/unit/DistributionCreator.t.sol +++ b/test/unit/DistributionCreator.t.sol @@ -950,7 +950,7 @@ contract DistributionCreatorForkTest is Test { DistributionCreator public creator; function setUp() public { - vm.createSelectFork(vm.envString("ETH_NODE_URI_ARBITRUM")); + vm.createSelectFork(vm.envString("ARBITRUM_NODE_URI")); creator = DistributionCreator(0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd); }